1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-23 01:44:22 +00:00

MenuBarComponent: Fix incorrect deactivation of the menu bar

Prior to this commit it was possible to get the menu bar deactivated
by moving the mouse to an adjacent menu item and then back again. If
the movement was quick enough the corresponding PopupMenu would be
dismissed and created again before the dismissal's async command
handler would run. The command handler would see that the dismissed
menu's index and the currently activated index are equal and
deactivate the menu bar.
This commit is contained in:
attila 2022-08-01 19:02:10 +02:00 committed by Attila Szarvas
parent 6aa926750e
commit c05ec5f9d0
2 changed files with 35 additions and 28 deletions

View file

@ -223,41 +223,47 @@ void MenuBarComponent::updateItemUnderMouse (Point<int> p)
void MenuBarComponent::showMenu (int index)
{
if (index != currentPopupIndex)
if (index == currentPopupIndex)
return;
const auto needToOpenNewSubMenu = isPositiveAndBelow (index, (int) itemComponents.size());
if (needToOpenNewSubMenu)
++numActiveMenus;
PopupMenu::dismissAllActiveMenus();
menuBarItemsChanged (nullptr);
setOpenItem (index);
setItemUnderMouse (index);
if (needToOpenNewSubMenu)
{
PopupMenu::dismissAllActiveMenus();
menuBarItemsChanged (nullptr);
const auto& itemComponent = itemComponents[(size_t) index];
auto m = model->getMenuForIndex (itemUnderMouse, itemComponent->getName());
setOpenItem (index);
setItemUnderMouse (index);
if (m.lookAndFeel == nullptr)
m.setLookAndFeel (&getLookAndFeel());
if (isPositiveAndBelow (index, (int) itemComponents.size()))
auto itemBounds = itemComponent->getBounds();
const auto callback = [ref = SafePointer<MenuBarComponent> (this), index] (int result)
{
const auto& itemComponent = itemComponents[(size_t) index];
auto m = model->getMenuForIndex (itemUnderMouse, itemComponent->getName());
if (ref != nullptr)
ref->menuDismissed (index, result);
};
if (m.lookAndFeel == nullptr)
m.setLookAndFeel (&getLookAndFeel());
auto itemBounds = itemComponent->getBounds();
const auto callback = [ref = SafePointer<MenuBarComponent> (this), index] (int result)
{
if (ref != nullptr)
ref->menuDismissed (index, result);
};
m.showMenuAsync (PopupMenu::Options().withTargetComponent (this)
.withTargetScreenArea (localAreaToGlobal (itemBounds))
.withMinimumWidth (itemBounds.getWidth()),
callback);
}
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);
}
//==============================================================================

View file

@ -119,7 +119,8 @@ private:
std::vector<std::unique_ptr<AccessibleItemComponent>> itemComponents;
Point<int> 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)
};