dontTriggerVisualFeedback not working on OS X menu items with modifier keys


#1

Continuing the discussion from Flickering in the native menu:

My application uses menus to advertise features and shortcut keys. In response to ApplicationCommandTarget::getCommandInfo, I always specify ApplicationCommandInfo::dontTriggerVisualFeedback for the result’s flags. However, on OS X, this only works for shortcut keys that have no modifiers (or use SPACE as a modifier). For shortcut keys defined utilizing the arrow keys, their use causes menu flashing, as does any shortcut key that includes CMD, OPTION, CTRL+SHIFT, or CMD+SHIFT modifiers.

Here’s the stack trace for the scenario where the ‘plain’ key honors the flag to not trigger visual feedback:

juce::ApplicationCommandManager::invoke(inf, asynchronously)
juce::KeyPressMappingSet::invokeCommand(commandID, key, isKeyDown, millisecsSinceKeyPressed, originatingComponent)
juce::KeyPressMappingSet::keyPressed(key, originatingComponent)
juce::ComponentPeer::handleKeyPress(keyInfo)
juce::ComponentPeer::handleKeyPress(keyCode, textCharacter)
juce::NSViewComponentPeer::handleKeyEvent(ev, isKeyDown)
juce::NSViewComponentPeer::redirectKeyDown(ev)
juce::JuceNSViewClass::keyDown(ev)
AppKit-[NSWindow _reallySendEvent:isDelayedEvent:]
AppKit-[NSWindow sendEvent:]

AppKit-[NSApplication sendEvent:]
AppKit-[NSApplication run]
juce::MessageManager::runDispatchLoop()
juce::JUCEApplicationBase::main()
juce::JUCEApplicationBase::main(argc, argv)
main(argc, argv)
start

Here’s a stack trace for a shortcut key that includes an offending modifier:

juce::NSViewComponentPeer::handleKeyEvent(ev, isKeyDown)
juce::NSViewComponentPeer::redirectKeyDown(ev)
juce::JuceMainMenuHandler::JuceMenuCallbackClass::menuItemInvoked(menuItemInvoked: item)
libsystem_trace.dylib-_os_activity_initiate
AppKit-[NSApplication sendAction:to:from:]
AppKit-[NSMenuItem _corePerformAction]
AppKit-[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] libsystem_trace.dylib-_os_activity_initiate
AppKit-[NSMenu performKeyEquivalent:]
AppKit-[NSApplication _handleKeyEquivalent:]

AppKit-[NSApplication sendEvent:]
AppKit-[NSApplication run]
juce::MessageManager::runDispatchLoop()
juce::JUCEApplicationBase::main()
juce::JUCEApplicationBase::main(argc, argv)
main(argc, argv)
start

Apparently, the operating system is matching shortcut keys with modifiers to menu item actions but sending ‘plain’ shortcut keys to the NSWindow to process as key events.

This may be why the scenario in the referenced post exhibits two flashes: one from [NSCarbonMenuImpl performActionWithHighlightingForItemAtInce] and one from JuceMainMenuHandler::flashMenuBar.

Is there a way to suppress visual feedback/menu flashing for shortcut keys utilizing modifiers that are shared with menu item actions? Is there a way to route all key handing to the NSWindow so the ApplicationCommandManager can handle the events?