diff --git a/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp b/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp index 99bec2c987..328b46f7c5 100644 --- a/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp +++ b/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp @@ -223,41 +223,47 @@ void MenuBarComponent::updateItemUnderMouse (Point p) void MenuBarComponent::showMenu (int index) { - if (index != currentPopupIndex) - { - PopupMenu::dismissAllActiveMenus(); - menuBarItemsChanged (nullptr); + if (index == currentPopupIndex) + return; - setOpenItem (index); - setItemUnderMouse (index); + const auto needToOpenNewSubMenu = isPositiveAndBelow (index, (int) itemComponents.size()); - if (isPositiveAndBelow (index, (int) itemComponents.size())) - { - const auto& itemComponent = itemComponents[(size_t) index]; - auto m = model->getMenuForIndex (itemUnderMouse, itemComponent->getName()); + if (needToOpenNewSubMenu) + ++numActiveMenus; - if (m.lookAndFeel == nullptr) - m.setLookAndFeel (&getLookAndFeel()); + PopupMenu::dismissAllActiveMenus(); + menuBarItemsChanged (nullptr); - auto itemBounds = itemComponent->getBounds(); + setOpenItem (index); + setItemUnderMouse (index); - const auto callback = [ref = SafePointer (this), index] (int result) - { - if (ref != nullptr) - ref->menuDismissed (index, result); - }; - - m.showMenuAsync (PopupMenu::Options().withTargetComponent (this) - .withTargetScreenArea (localAreaToGlobal (itemBounds)) - .withMinimumWidth (itemBounds.getWidth()), - callback); - } + if (needToOpenNewSubMenu) + { + const auto& itemComponent = itemComponents[(size_t) index]; + auto m = model->getMenuForIndex (itemUnderMouse, itemComponent->getName()); + + if (m.lookAndFeel == nullptr) + m.setLookAndFeel (&getLookAndFeel()); + + auto itemBounds = itemComponent->getBounds(); + + const auto callback = [ref = SafePointer (this), index] (int result) + { + if (ref != nullptr) + ref->menuDismissed (index, result); + }; + + m.showMenuAsync (PopupMenu::Options().withTargetComponent (this) + .withTargetScreenArea (localAreaToGlobal (itemBounds)) + .withMinimumWidth (itemBounds.getWidth()), + callback); } } void MenuBarComponent::menuDismissed (int topLevelIndex, int itemId) { - topLevelIndexClicked = topLevelIndex; + topLevelIndexDismissed = topLevelIndex; + --numActiveMenus; postCommandMessage (itemId); } @@ -265,11 +271,11 @@ void MenuBarComponent::handleCommandMessage (int commandId) { updateItemUnderMouse (getMouseXYRelative()); - if (currentPopupIndex == topLevelIndexClicked) + if (numActiveMenus == 0) setOpenItem (-1); if (commandId != 0 && model != nullptr) - model->menuItemSelected (commandId, topLevelIndexClicked); + model->menuItemSelected (commandId, topLevelIndexDismissed); } //============================================================================== diff --git a/modules/juce_gui_basics/menus/juce_MenuBarComponent.h b/modules/juce_gui_basics/menus/juce_MenuBarComponent.h index 602e7bf0a6..d17613168c 100644 --- a/modules/juce_gui_basics/menus/juce_MenuBarComponent.h +++ b/modules/juce_gui_basics/menus/juce_MenuBarComponent.h @@ -119,7 +119,8 @@ private: std::vector> itemComponents; Point lastMousePos; - int itemUnderMouse = -1, currentPopupIndex = -1, topLevelIndexClicked = 0; + int itemUnderMouse = -1, currentPopupIndex = -1, topLevelIndexDismissed = 0; + int numActiveMenus = 0; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MenuBarComponent) };