提交 61a45b20 编写于 作者: D dmarkov

8169589: [macosx] Activating a JDialog puts to back another dialog

Reviewed-by: anthony, serb
上级 723b6a08
...@@ -31,6 +31,8 @@ import java.awt.event.*; ...@@ -31,6 +31,8 @@ import java.awt.event.*;
import java.awt.peer.WindowPeer; import java.awt.peer.WindowPeer;
import java.beans.*; import java.beans.*;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
...@@ -40,6 +42,8 @@ import java.util.Objects; ...@@ -40,6 +42,8 @@ import java.util.Objects;
import javax.swing.*; import javax.swing.*;
import sun.awt.*; import sun.awt.*;
import sun.awt.AWTAccessor.ComponentAccessor;
import sun.awt.AWTAccessor.WindowAccessor;
import sun.java2d.SurfaceData; import sun.java2d.SurfaceData;
import sun.java2d.opengl.CGLSurfaceData; import sun.java2d.opengl.CGLSurfaceData;
import sun.lwawt.*; import sun.lwawt.*;
...@@ -1057,31 +1061,73 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo ...@@ -1057,31 +1061,73 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
return true; return true;
} }
private void orderAboveSiblings() { private boolean isOneOfOwnersOrSelf(CPlatformWindow window) {
if (owner == null) { while (window != null) {
return; if (this == window) {
return true;
}
window = window.owner;
} }
return false;
}
// NOTE: the logic will fail if we have a hierarchy like: private CPlatformWindow getRootOwner() {
// visible root owner CPlatformWindow rootOwner = this;
// invisible owner while (rootOwner.owner != null) {
// visible dialog rootOwner = rootOwner.owner;
// 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
owner.execute(nsWindowOwnerPtr->{
execute(nsWindowSelfPtr->{
CWrapper.NSWindow.orderFront(nsWindowOwnerPtr);
CWrapper.NSWindow.orderWindow(nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove, nsWindowOwnerPtr);
});
});
} }
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()) {
rootOwner.execute(CWrapper.NSWindow::orderFront);
}
final WindowAccessor windowAccessor = AWTAccessor.getWindowAccessor();
orderAboveSiblingsImpl(windowAccessor.getOwnedWindows(rootOwner.target));
}
private void orderAboveSiblingsImpl(Window[] windows) {
ArrayList<Window> childWindows = new ArrayList<Window>();
final ComponentAccessor componentAccessor = AWTAccessor.getComponentAccessor();
final WindowAccessor windowAccessor = AWTAccessor.getWindowAccessor();
// Go through the list of windows and perform ordering.
for (Window w : windows) {
final Object p = componentAccessor.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)) {
pw.execute(CWrapper.NSWindow::orderFront);
} else {
pw.owner.execute(ownerPtr -> {
pw.execute(ptr -> {
CWrapper.NSWindow.orderWindow(ptr, CWrapper.NSWindow.NSWindowAbove, ownerPtr);
});
});
}
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.
childWindows.addAll(Arrays.asList(windowAccessor.getOwnedWindows(w)));
}
// 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[0]));
}
} }
protected void applyWindowLevel(Window target) { protected void applyWindowLevel(Window target) {
......
...@@ -4100,6 +4100,10 @@ public class Window extends Container implements Accessible { ...@@ -4100,6 +4100,10 @@ public class Window extends Container implements Accessible {
public void setTrayIconWindow(Window w, boolean isTrayIconWindow) { public void setTrayIconWindow(Window w, boolean isTrayIconWindow) {
w.isTrayIconWindow = isTrayIconWindow; w.isTrayIconWindow = isTrayIconWindow;
} }
public Window[] getOwnedWindows(Window w) {
return w.getOwnedWindows_NoClientCode();
}
}); // WindowAccessor }); // WindowAccessor
} // static } // static
......
...@@ -334,6 +334,12 @@ public final class AWTAccessor { ...@@ -334,6 +334,12 @@ public final class AWTAccessor {
* Marks the specified window as an utility window for TrayIcon. * Marks the specified window as an utility window for TrayIcon.
*/ */
void setTrayIconWindow(Window w, boolean isTrayIconWindow); void setTrayIconWindow(Window w, boolean isTrayIconWindow);
/**
* Return an array containing all the windows this
* window currently owns.
*/
Window[] getOwnedWindows(Window w);
} }
/** /**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册