diff --git a/examples/audio plugin host/Source/GraphEditorPanel.cpp b/examples/audio plugin host/Source/GraphEditorPanel.cpp index 1824551fe5..e25a7516b8 100644 --- a/examples/audio plugin host/Source/GraphEditorPanel.cpp +++ b/examples/audio plugin host/Source/GraphEditorPanel.cpp @@ -1141,3 +1141,8 @@ void GraphDocumentComponent::createNewPlugin (const PluginDescription* desc, int { graphPanel->createNewPlugin (desc, x, y); } + +void GraphDocumentComponent::unfocusKeyboardComponent() +{ + keyboardComp->unfocusAllComponents(); +} diff --git a/examples/audio plugin host/Source/GraphEditorPanel.h b/examples/audio plugin host/Source/GraphEditorPanel.h index dde5654e2b..9b67ed2b99 100644 --- a/examples/audio plugin host/Source/GraphEditorPanel.h +++ b/examples/audio plugin host/Source/GraphEditorPanel.h @@ -96,6 +96,9 @@ public: //============================================================================== void resized(); + //============================================================================== + void unfocusKeyboardComponent(); + private: //============================================================================== AudioDeviceManager* deviceManager; diff --git a/examples/audio plugin host/Source/MainHostWindow.cpp b/examples/audio plugin host/Source/MainHostWindow.cpp index 8b24be859f..d59c112ab6 100644 --- a/examples/audio plugin host/Source/MainHostWindow.cpp +++ b/examples/audio plugin host/Source/MainHostWindow.cpp @@ -291,6 +291,14 @@ void MainHostWindow::menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/ } } +void MainHostWindow::menuBarActivated (bool isActivated) +{ + GraphDocumentComponent* const graphEditor = getGraphEditor(); + + if (graphEditor != nullptr && isActivated) + graphEditor->unfocusKeyboardComponent(); +} + void MainHostWindow::createPlugin (const PluginDescription* desc, int x, int y) { GraphDocumentComponent* const graphEditor = getGraphEditor(); diff --git a/examples/audio plugin host/Source/MainHostWindow.h b/examples/audio plugin host/Source/MainHostWindow.h index ccde2ad8b8..fe4fda2b8d 100644 --- a/examples/audio plugin host/Source/MainHostWindow.h +++ b/examples/audio plugin host/Source/MainHostWindow.h @@ -70,6 +70,8 @@ public: void fileDragExit (const StringArray& files); void filesDropped (const StringArray& files, int, int); + void menuBarActivated (bool isActive); + StringArray getMenuBarNames(); PopupMenu getMenuForIndex (int topLevelMenuIndex, const String& menuName); void menuItemSelected (int menuItemID, int topLevelMenuIndex); diff --git a/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp b/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp index 2f8c2ad2a2..1c1c9d9db2 100644 --- a/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp +++ b/modules/juce_audio_utils/gui/juce_MidiKeyboardComponent.cpp @@ -90,7 +90,6 @@ MidiKeyboardComponent::MidiKeyboardComponent (MidiKeyboardState& s, Orientation colourChanged(); setWantsKeyboardFocus (true); - setLosesFocusWhenAccessingMainMenuBar (true); state.addListener (this); diff --git a/modules/juce_gui_basics/components/juce_Component.h b/modules/juce_gui_basics/components/juce_Component.h index 14c9384810..3852448e29 100644 --- a/modules/juce_gui_basics/components/juce_Component.h +++ b/modules/juce_gui_basics/components/juce_Component.h @@ -880,18 +880,6 @@ public: bool& allowsClicksOnChildComponents) const noexcept; - /** Changes the focus behavior when the main menu bar is accessed. - - If set to true, then clicking the main menu bar on Mac will unfocus the component. - */ - void setLosesFocusWhenAccessingMainMenuBar (bool loseFocus) noexcept { flags.shouldReleaseFocusOnMainMenuBarAccess = loseFocus; } - - /** Retrieves the focus behavior when the main menu bar is accessed. - - Returns true if clicking the main menu bar on Mac will unfocus this component. - */ - bool getLosesFocusWhenAccessingMainMenuBar() const noexcept { return flags.shouldReleaseFocusOnMainMenuBarAccess; } - /** Returns true if a given point lies within this component or one of its children. Never override this method! Use hitTest to create custom hit regions. @@ -2278,28 +2266,27 @@ private: struct ComponentFlags { - bool hasHeavyweightPeerFlag : 1; - bool visibleFlag : 1; - bool opaqueFlag : 1; - bool ignoresMouseClicksFlag : 1; - bool allowChildMouseClicksFlag : 1; - bool wantsFocusFlag : 1; - bool isFocusContainerFlag : 1; - bool dontFocusOnMouseClickFlag : 1; - bool alwaysOnTopFlag : 1; - bool bufferToImageFlag : 1; - bool bringToFrontOnClickFlag : 1; - bool repaintOnMouseActivityFlag : 1; - bool isDisabledFlag : 1; - bool childCompFocusedFlag : 1; - bool dontClipGraphicsFlag : 1; - bool mouseDownWasBlocked : 1; - bool isMoveCallbackPending : 1; - bool isResizeCallbackPending : 1; + bool hasHeavyweightPeerFlag : 1; + bool visibleFlag : 1; + bool opaqueFlag : 1; + bool ignoresMouseClicksFlag : 1; + bool allowChildMouseClicksFlag : 1; + bool wantsFocusFlag : 1; + bool isFocusContainerFlag : 1; + bool dontFocusOnMouseClickFlag : 1; + bool alwaysOnTopFlag : 1; + bool bufferToImageFlag : 1; + bool bringToFrontOnClickFlag : 1; + bool repaintOnMouseActivityFlag : 1; + bool isDisabledFlag : 1; + bool childCompFocusedFlag : 1; + bool dontClipGraphicsFlag : 1; + bool mouseDownWasBlocked : 1; + bool isMoveCallbackPending : 1; + bool isResizeCallbackPending : 1; #if JUCE_DEBUG - bool isInsidePaintCall : 1; + bool isInsidePaintCall : 1; #endif - bool shouldReleaseFocusOnMainMenuBarAccess : 1; }; union diff --git a/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp b/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp index 8d746c4fc4..b979ba4810 100644 --- a/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp +++ b/modules/juce_gui_basics/menus/juce_MenuBarComponent.cpp @@ -143,6 +143,11 @@ void MenuBarComponent::setOpenItem (int index) { if (currentPopupIndex != index) { + if (currentPopupIndex < 0 && index >= 0) + model->handleMenuBarActivate (true); + else if (currentPopupIndex >= 0 && index < 0) + model->handleMenuBarActivate (false); + repaintMenuItem (currentPopupIndex); currentPopupIndex = index; repaintMenuItem (currentPopupIndex); diff --git a/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp b/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp index d93642ffaa..ccfcbc49b5 100644 --- a/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp +++ b/modules/juce_gui_basics/menus/juce_MenuBarModel.cpp @@ -82,3 +82,12 @@ void MenuBarModel::applicationCommandListChanged() { menuItemsChanged(); } + +void MenuBarModel::handleMenuBarActivate (bool isActive) +{ + menuBarActivated (isActive); + listeners.call (&MenuBarModel::Listener::menuBarActivated, this, isActive); +} + +void MenuBarModel::menuBarActivated (bool) {} +void MenuBarModel::Listener::menuBarActivated (MenuBarModel*, bool) {} diff --git a/modules/juce_gui_basics/menus/juce_MenuBarModel.h b/modules/juce_gui_basics/menus/juce_MenuBarModel.h index 0fc06e7f9d..8d38c8e48c 100644 --- a/modules/juce_gui_basics/menus/juce_MenuBarModel.h +++ b/modules/juce_gui_basics/menus/juce_MenuBarModel.h @@ -88,6 +88,10 @@ public: */ virtual void menuCommandInvoked (MenuBarModel* menuBarModel, const ApplicationCommandTarget::InvocationInfo& info) = 0; + + /** Called when the menu bar is first activated or when the user finished interacting + with the menu bar. */ + virtual void menuBarActivated (MenuBarModel* menuBarModel, bool isActive); }; /** Registers a listener for callbacks when the menu items in this model change. @@ -126,6 +130,12 @@ public: virtual void menuItemSelected (int menuItemID, int topLevelMenuIndex) = 0; + /** This is called when the user starts/stops navigating the maenu bar. + + @param isActive true when the user starts navigating the menu bar + */ + virtual void menuBarActivated (bool isActive); + //============================================================================== #if JUCE_MAC || DOXYGEN /** OSX ONLY - Sets the model that is currently being shown as the main @@ -167,7 +177,8 @@ public: void applicationCommandListChanged() override; /** @internal */ void handleAsyncUpdate() override; - + /** @internal */ + void handleMenuBarActivate (bool isActive); private: ApplicationCommandManager* manager; ListenerList listeners; diff --git a/modules/juce_gui_basics/native/juce_mac_MainMenu.mm b/modules/juce_gui_basics/native/juce_mac_MainMenu.mm index f0e1d7f183..567395104d 100644 --- a/modules/juce_gui_basics/native/juce_mac_MainMenu.mm +++ b/modules/juce_gui_basics/native/juce_mac_MainMenu.mm @@ -728,19 +728,13 @@ static void mainMenuTrackingChanged (bool isTracking) { menuHandler->isOpen = isTracking; - if (isTracking) + if (MenuBarModel* model = menuHandler->currentModel) + model->handleMenuBarActivate (isTracking); + + if (menuHandler->defferedUpdateRequested && ! isTracking) { - if (Component* c = Component::getCurrentlyFocusedComponent()) - if (c->getLosesFocusWhenAccessingMainMenuBar()) - c->unfocusAllComponents(); - } - else - { - if (menuHandler->defferedUpdateRequested) - { - menuHandler->defferedUpdateRequested = false; - menuHandler->menuBarItemsChanged (menuHandler->currentModel); - } + menuHandler->defferedUpdateRequested = false; + menuHandler->menuBarItemsChanged (menuHandler->currentModel); } } }