Skip to content

Commit

Permalink
NSViewComponentPeer: Attempt to avoid reentrant calls to makeKeyWindow
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
reuk committed Feb 6, 2023
1 parent f5aa881 commit 408f603
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ void toFront (bool makeActiveWindow) override
{
++insideToFrontCall;

if (makeActiveWindow)
if (makeActiveWindow && ! inBecomeKeyWindow)
[window makeKeyAndOrderFront: nil];
else
[window orderFront: nil];
Expand Down Expand Up @@ -1541,7 +1541,9 @@ void grabFocus() override
{
if (window != nil)
{
[window makeKeyWindow];
if (! inBecomeKeyWindow)
[window makeKeyWindow];

[window makeFirstResponder: view];

viewFocusGain();
Expand Down Expand Up @@ -1622,7 +1624,7 @@ bool sendEventToInputContextOrComponent (NSEvent* ev)
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;

Expand Down Expand Up @@ -2453,6 +2455,10 @@ static NSDragOperation draggingUpdated (id self, SEL, id<NSDraggingInfo> sender)

if (auto* owner = getOwner (self))
{
jassert (! owner->inBecomeKeyWindow);

const ScopedValueSetter scope { owner->inBecomeKeyWindow, true };

if (owner->canBecomeKeyWindow())
{
owner->becomeKeyWindow();
Expand Down

0 comments on commit 408f603

Please sign in to comment.