From 408f6030e6dd2a54193d9ee0953ed4c7455bea22 Mon Sep 17 00:00:00 2001 From: reuk Date: Mon, 6 Feb 2023 19:36:28 +0000 Subject: [PATCH] NSViewComponentPeer: Attempt to avoid reentrant calls to makeKeyWindow AUv2 plugins on Arm that are hosted out-of-process (e.g. in Logic 10.7) can sometimes crash due to endlessly recursing through becomeKeyWindow. This tends to happen when displaying a secondary window in a plugin, e.g. an AlertWindow, then clicking on a secondary app, then clicking back on the AlertWindow. To avoid this case, we check that the peer isn't already key before calling makeKeyWindow. Unfortunately, we can't use isKeyWindow to avoid the recursion because this may not return true until after becomeKeyWindow has returned. --- .../native/juce_mac_NSViewComponentPeer.mm | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index 95321245ca..d5f25718d9 100644 --- a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -558,7 +558,7 @@ public: { ++insideToFrontCall; - if (makeActiveWindow) + if (makeActiveWindow && ! inBecomeKeyWindow) [window makeKeyAndOrderFront: nil]; else [window orderFront: nil]; @@ -1541,7 +1541,9 @@ public: { if (window != nil) { - [window makeKeyWindow]; + if (! inBecomeKeyWindow) + [window makeKeyWindow]; + [window makeFirstResponder: view]; viewFocusGain(); @@ -1622,7 +1624,7 @@ public: bool isFirstLiveResize = false, viewCannotHandleEvent = false; bool isStretchingTop = false, isStretchingLeft = false, isStretchingBottom = false, isStretchingRight = false; bool windowRepresentsFile = false; - bool isAlwaysOnTop = false, wasAlwaysOnTop = false; + bool isAlwaysOnTop = false, wasAlwaysOnTop = false, inBecomeKeyWindow = false; String stringBeingComposed; int startOfMarkedTextInTextInputTarget = 0; @@ -2453,6 +2455,10 @@ struct JuceNSWindowClass : public NSViewComponentPeerWrapperinBecomeKeyWindow); + + const ScopedValueSetter scope { owner->inBecomeKeyWindow, true }; + if (owner->canBecomeKeyWindow()) { owner->becomeKeyWindow();