Ticket #4930: menu-kb-nav2.patch

File menu-kb-nav2.patch, 5.0 KB (added by Ziusudra, 14 years ago)
  • src/kits/interface/Menu.cpp

     
    372372    // when called on input_server initialization, since it tries
    373373    // to send a synchronous message to itself (input_server is
    374374    // a BApplication)
    375 
    376375    BMenu::sAltAsCommandKey = true;
    377376    key_map* keys = NULL;
    378377    char* chars = NULL;
     
    515514                _SelectNextItem(fSelected, true);
    516515            else {
    517516                if (fSelected && fSelected->Submenu()) {
    518                     _SelectItem(fSelected, true, true);
     517                    fSelected->Submenu()->_SetStickyMode(true);
     518                        // fix me: this shouldn't be needed but dynamic menus
     519                        // aren't getting it set correctly when keyboard
     520                        // navigating, which aborts the attach
     521                    _SelectItem(fSelected, true, true, true);
    519522                } else if (dynamic_cast<BMenuBar*>(Supermenu())) {
    520523                    // if we have no submenu and we're an
    521524                    // item in the top menu below the menubar,
     
    14621465
    14631466
    14641467bool
    1465 BMenu::_Show(bool selectFirstItem)
     1468BMenu::_Show(bool selectFirstItem, bool keyDown)
    14661469{
    14671470    // See if the supermenu has a cached menuwindow,
    14681471    // and use that one if possible.
     
    14861489        return false;
    14871490
    14881491    if (window->Lock()) {
     1492        bool attachAborted = false;
    14891493        fAttachAborted = false;
     1494
     1495        // When the keyboard was used to show a dynamic menu, we build it
     1496        // here to prevent aborting because the mouse pointer is not over
     1497        // the superitem. Otherwise, AttachedToWindow() will build it.
     1498        if (keyDown) {
     1499            BMenuItem* superItem = Superitem();
     1500            BMenu* superMenu = Supermenu();
     1501            if (AddDynamicItem(B_INITIAL_ADD)) {
     1502                do {
     1503                    if (superMenu != NULL
     1504                            && !superMenu->_OkToProceed(superItem, keyDown)) {
     1505                        AddDynamicItem(B_ABORT);
     1506                        attachAborted = true;
     1507                        break;
     1508                    }
     1509                } while (AddDynamicItem(B_PROCESSING));
     1510            }
     1511            if (attachAborted) {
     1512                if (ourWindow)
     1513                    window->Quit();
     1514                else
     1515                    window->Unlock();
     1516                return false;
     1517            }
     1518        }
     1519
    14901520        window->AttachMenu(this);
    14911521
    14921522        if (ItemAt(0) != NULL) {
    14931523            float width, height;
    14941524            ItemAt(0)->GetContentSize(&width, &height);
    1495 
    14961525            window->SetSmallStep(ceilf(height));
    14971526        }
    14981527
     
    24992528
    25002529
    25012530void
    2502 BMenu::_SelectItem(BMenuItem* menuItem, bool showSubmenu, bool selectFirstItem)
     2531BMenu::_SelectItem(BMenuItem* menuItem, bool showSubmenu,
     2532                        bool selectFirstItem, bool keyDown)
    25032533{
    25042534    // Avoid deselecting and then reselecting the same item
    25052535    // which would cause flickering
     
    25192549    if (fSelected != NULL && showSubmenu) {
    25202550        BMenu* subMenu = fSelected->Submenu();
    25212551        if (subMenu != NULL && subMenu->Window() == NULL) {
    2522             if (!subMenu->_Show(selectFirstItem)) {
     2552            if (!subMenu->_Show(selectFirstItem, keyDown)) {
    25232553                // something went wrong, deselect the item
    25242554                fSelected->Select(false);
    25252555                fSelected = NULL;
     
    27292759
    27302760
    27312761bool
    2732 BMenu::_OkToProceed(BMenuItem* item)
     2762BMenu::_OkToProceed(BMenuItem* item, bool keyDown)
    27332763{
    27342764    BPoint where;
    27352765    ulong buttons;
     
    27422772    // BeOS seems to do something similar. This could also be a bug in
    27432773    // Deskbar, though.
    27442774    if ((buttons != 0 && stickyMode)
    2745         || ((dynamic_cast<BMenuBar*>(this) == NULL
    2746             && (buttons == 0 && !stickyMode)) || _HitTestItems(where) != item))
     2775            || (dynamic_cast<BMenuBar*>(this) == NULL
     2776                && (buttons == 0 && !stickyMode))
     2777            || ((_HitTestItems(where) != item) && !keyDown))
    27472778        return false;
    27482779
    27492780    return true;
  • headers/os/interface/Menu.h

     
    183183            BMenu&              operator=(const BMenu& other);
    184184
    185185            void                _InitData(BMessage* archive);
    186             bool                _Show(bool selectFirstItem = false);
     186            bool                _Show(bool selectFirstItem = false,
     187                                    bool keyDown = false);
    187188            void                _Hide();
    188189            BMenuItem*          _Track(int* action, long start = -1);
    189190
     
    212213            void                _ComputeColumnLayout(int32 index, bool bestFit,
    213214                                    bool moveItems, BRect& outRect);
    214215            void                _ComputeRowLayout(int32 index, bool bestFit,
    215                                     bool moveItems, BRect& outRect);       
     216                                    bool moveItems, BRect& outRect);
    216217            void                _ComputeMatrixLayout(BRect& outRect);
    217218
    218219            BRect               _CalcFrame(BPoint where, bool* scrollOn);
     
    235236            void                _Uninstall();
    236237            void                _SelectItem(BMenuItem* item,
    237238                                    bool showSubmenu = true,
    238                                     bool selectFirstItem = false);
     239                                    bool selectFirstItem = false,
     240                                    bool keyDown = false);
    239241            bool                _SelectNextItem(BMenuItem* item, bool forward);
    240242            BMenuItem*          _NextItem(BMenuItem* item, bool forward) const;
    241243            void                _SetIgnoreHidden(bool on);
     
    246248                                    uint32& trigger,
    247249                                    BPrivate::TriggerList& triggers);
    248250            void                _UpdateWindowViewSize(const bool &updatePosition);
    249             bool                _OkToProceed(BMenuItem* item);
     251            bool                _OkToProceed(BMenuItem* item,
     252                                    bool keyDown = false);
    250253
    251254            bool                _CustomTrackingWantsToQuit();
    252255