--- old/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java 2016-11-26 13:39:21.000000000 +0300 +++ new/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java 2016-11-26 13:39:21.000000000 +0300 @@ -33,6 +33,8 @@ import java.awt.event.*; import java.beans.*; import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; import javax.swing.*; @@ -1063,29 +1065,69 @@ return true; } - private void orderAboveSiblings() { - if (owner == null) { - return; + private boolean isOneOfOwnersOrSelf(CPlatformWindow window) { + while (window != null) { + if (this == window) { + return true; + } + window = window.owner; } + return false; + } - // NOTE: the logic will fail if we have a hierarchy like: - // visible root owner - // invisible owner - // visible dialog - // However, this is an unlikely scenario for real life apps - if (owner.isVisible()) { - // Recursively pop up the windows from the very bottom so that only - // the very top-most one becomes the main window - owner.orderAboveSiblings(); - - // Order the window to front of the stack of child windows - final long nsWindowSelfPtr = getNSWindowPtr(); - final long nsWindowOwnerPtr = owner.getNSWindowPtr(); - CWrapper.NSWindow.orderFront(nsWindowOwnerPtr); - CWrapper.NSWindow.orderWindow(nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove, nsWindowOwnerPtr); + private CPlatformWindow getRootOwner() { + CPlatformWindow rootOwner = this; + while (rootOwner.owner != null) { + rootOwner = rootOwner.owner; } + return rootOwner; + } - applyWindowLevel(target); + private void orderAboveSiblings() { + // Recursively pop up the windows from the very bottom, (i.e. root owner) so that + // the windows are ordered above their nearest owner; ancestors of the window, + // which is going to become 'main window', are placed above their siblings. + CPlatformWindow rootOwner = getRootOwner(); + if (rootOwner.isVisible()) { + CWrapper.NSWindow.orderFront(rootOwner.getNSWindowPtr()); + } + orderAboveSiblingsImpl(rootOwner.target.getOwnedWindows()); + } + + private void orderAboveSiblingsImpl(Window[] windows) { + ArrayList childWindows = new ArrayList(); + + final ComponentAccessor acc = AWTAccessor.getComponentAccessor(); + + // Go through the list of windows and perform ordering. + for (Window w : windows) { + final Object p = acc.getPeer(w); + if (p instanceof LWWindowPeer) { + CPlatformWindow pw = (CPlatformWindow)((LWWindowPeer)p).getPlatformWindow(); + if (pw != null && pw.isVisible()) { + // If the window is one of ancestors of 'main window' or is going to become main by itself, + // the window should be ordered above its siblings; otherwise the window is just ordered + // above its nearest parent. + if (pw.isOneOfOwnersOrSelf(this)) { + CWrapper.NSWindow.orderFront(pw.getNSWindowPtr()); + } else { + CWrapper.NSWindow.orderWindow(pw.getNSWindowPtr(), CWrapper.NSWindow.NSWindowAbove, + pw.owner.getNSWindowPtr()); + } + pw.applyWindowLevel(w); + } + } + // Retrieve the child windows for each window from the list and store them for future use. + // Note: we collect data about child windows even for invisible owners, since they may have + // visible children. + java.util.List pwChildWindows = new ArrayList(Arrays.asList(w.getOwnedWindows())); + childWindows.addAll(pwChildWindows); + } + // If some windows, which have just been ordered, have any child windows, let's start new iteration + // and order these child windows. + if (!childWindows.isEmpty()) { + orderAboveSiblingsImpl(childWindows.toArray(new Window[childWindows.size()])); + } } protected void applyWindowLevel(Window target) {