From 3195db14a4db1fb8f367087af97e237dd397ac9e Mon Sep 17 00:00:00 2001 From: ed Date: Tue, 15 Jun 2021 10:14:56 +0100 Subject: [PATCH] macOS: Check subview position in ComponentPeer::toFront() and toBehind() before re-ordering subviews for shared windows This commit also removes the subview from its superview's subview array before re-ordering as the macOS docs don't make any guarantees about what happens when adding a subview that is already contained in the array. --- .../native/juce_mac_NSViewComponentPeer.mm | 42 ++++++++++++++++--- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm index a1e1662d69..b933f2a954 100644 --- a/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm +++ b/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm @@ -479,9 +479,22 @@ public: void toFront (bool makeActiveWindow) override { if (isSharedWindow) - [[view superview] addSubview: view - positioned: NSWindowAbove - relativeTo: nil]; + { + NSView* superview = [view superview]; + NSMutableArray* subviews = [NSMutableArray arrayWithArray: [superview subviews]]; + + const auto isFrontmost = [[subviews lastObject] isEqual: view]; + + if (! isFrontmost) + { + [view retain]; + [subviews removeObject: view]; + [subviews addObject: view]; + + [superview setSubviews: subviews]; + [view release]; + } + } if (window != nil && component.isVisible()) { @@ -508,9 +521,26 @@ public: { if (isSharedWindow) { - [[view superview] addSubview: view - positioned: NSWindowBelow - relativeTo: otherPeer->view]; + NSView* superview = [view superview]; + NSMutableArray* subviews = [NSMutableArray arrayWithArray: [superview subviews]]; + + const auto otherViewIndex = [subviews indexOfObject: otherPeer->view]; + + if (otherViewIndex == NSNotFound) + return; + + const auto isBehind = [subviews indexOfObject: view] < otherViewIndex; + + if (! isBehind) + { + [view retain]; + [subviews removeObject: view]; + [subviews insertObject: view + atIndex: otherViewIndex]; + + [superview setSubviews: subviews]; + [view release]; + } } else if (component.isVisible()) {