< prev index next >

src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java

Print this page

        

@@ -31,10 +31,12 @@
 import java.awt.*;
 import java.awt.Dialog.ModalityType;
 import java.awt.event.*;
 import java.beans.*;
 import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
 
 import javax.swing.*;
 
 import sun.awt.*;
 import sun.awt.AWTAccessor.ComponentAccessor;

@@ -1061,33 +1063,64 @@
         CWrapper.NSWindow.makeMainWindow(nsWindowPtr);
 
         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() {
+        CPlatformWindow rootOwner = getRootOwner();
+        CWrapper.NSWindow.orderFront(rootOwner.getNSWindowPtr());
+        orderAboveSiblingsImpl(rootOwner.target.getOwnedWindows(), this);
+    }
+
+    private void orderAboveSiblingsImpl(Window[] windows, CPlatformWindow activeWindow) {
+        ArrayList<Window> childWindows = new ArrayList<Window>();
+
+        final ComponentAccessor acc = AWTAccessor.getComponentAccessor();
+
+        // Go through the list of windows and order them above their nearest parent.
+        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 a window is active window or one of active window parent, the window should be ordered
+                    // above its siblings; otherwise the window is just ordered above its nearest parent.
+                    if (pw.isOneOfOwnersOrSelf(activeWindow)) {
+                        CWrapper.NSWindow.orderFront(pw.getNSWindowPtr());
+                    } else {
+                        CWrapper.NSWindow.orderWindow(pw.getNSWindowPtr(), CWrapper.NSWindow.NSWindowAbove,
+                                pw.owner.getNSWindowPtr());
+                    }
+                    pw.applyWindowLevel(w);
+                    // Collect information about child windows and store it for future use.
+                    java.util.List<Window> pwChildWindows = new ArrayList<Window>(Arrays.asList(w.getOwnedWindows()));
+                    childWindows.addAll(pwChildWindows);
+                }
+            }
+        }
+        // Start new iteration, if any.
+        if (!childWindows.isEmpty()) {
+            orderAboveSiblingsImpl(childWindows.toArray(new Window[childWindows.size()]), activeWindow);
+        }
     }
 
     protected void applyWindowLevel(Window target) {
         if (target.isAlwaysOnTop() && target.getType() != Window.Type.POPUP) {
             CWrapper.NSWindow.setLevel(getNSWindowPtr(), CWrapper.NSWindow.NSFloatingWindowLevel);
< prev index next >