< 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,73 @@
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() {
+ // 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<Window> childWindows = new ArrayList<Window>();
+
+ 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<Window> pwChildWindows = new ArrayList<Window>(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) {
if (target.isAlwaysOnTop() && target.getType() != Window.Type.POPUP) {
CWrapper.NSWindow.setLevel(getNSWindowPtr(), CWrapper.NSWindow.NSFloatingWindowLevel);
< prev index next >