BUG: Once a component is focused, Mac global Menubar won’t flash in response to KeyShortcut

This seems a bug to me. Or I would love to know a solution or workaround.

I have created a simple project to demonstrate this. It is the MenusDemo from DemoRunner, with a couple buttons.

JUCE 7.0.0. MacOS 10.14.6 if it makes any difference.

MenusDemoFlash.zip (18.5 KB)

  1. Compile and launch the project. Without doing anything else, use Command+R and Command+G to change the colors. The MacMenuBar flashes in response.
  2. Click anywhere in the content of the window. Now try those commands again. They still work; the colors change, but the Mac Menubar no longer flashes.
  3. Click the “unfocusAllComponents” button (which calls Component::unfocusAllComponents()). Now try those commands again. Now the MacMenubar flashes again.
  4. Click the “another button” button. Now try those commands again. No flashing.

When first launched (and no components are focused), invoking via keyPress comes in through juce_mac_MainMenu.mm invoke(), which contains this:

if (item.commandManager != nullptr)
{
    ApplicationCommandTarget::InvocationInfo info (item.itemID);
    info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromMenu;

    item.commandManager->invoke (info, true);
}

So here, even though you just used a KeyPress, it sets invocationMethod to InvocationInfo::fromMenu.

However, once a component is focused and the app is using the ApplicationCommandManager, invoking via KeyPress comes in through KeyPressMappingSet::invokeCommand() which contains this line:

    info.invocationMethod = ApplicationCommandTarget::InvocationInfo::fromKeyPress;

Then, both of these lead to juce_Mac_MainMenu.mm, where we have the following code:

    void menuCommandInvoked (MenuBarModel*, const ApplicationCommandTarget::InvocationInfo& info) override
    {
        if ((info.commandFlags & ApplicationCommandInfo::dontTriggerVisualFeedback) == 0
              && info.invocationMethod != ApplicationCommandTarget::InvocationInfo::fromKeyPress)
            if (auto* item = findMenuItemWithCommandID (getMainMenuBar(), info.commandID))
                flashMenuBar ([item menu]);
    }

… which specifically does NOT flash if it’s invoked by KeyPress.

So when everything is unfocused, menuCommandInvoked gets called with InvocationInfo::fromMenu, even though you used a keyPress, but once a component is focused, it gets called with InvocationInfo::fromKeyPress and no longer flashes. I don’t quite get it.

This does not seem logical behavior, nor standard MacOS behavior. Correct me if I am wrong. Thanks!

PS: the Projucer does the same behaviour. Launch it without a specific project, close the new project dialog if it is open. Now no windows are open. Try the Command+N command (New Project) - the File Menu will flash as it responds. Once a window is open and components are focused, no more flashing.

Bumping this, because it seems a bug.

Note that if you comment out this line in juce_Mac_MainMenu.mm, the Mac Global MenuBar flashes all the time in response to key shortcuts (like it should):

    void menuCommandInvoked (MenuBarModel*, const ApplicationCommandTarget::InvocationInfo& info) override
    {
        if ((info.commandFlags & ApplicationCommandInfo::dontTriggerVisualFeedback) == 0)   // add closed parentheses
//             && info.invocationMethod != ApplicationCommandTarget::InvocationInfo::fromKeyPress) // remove
            if (auto* item = findMenuItemWithCommandID (getMainMenuBar(), info.commandID))
                flashMenuBar ([item menu]);
    }