提交 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.*;
import java.awt.peer.WindowPeer;
import java.beans.*;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
......@@ -40,6 +42,8 @@ import java.util.Objects;
import javax.swing.*;
import sun.awt.*;
import sun.awt.AWTAccessor.ComponentAccessor;
import sun.awt.AWTAccessor.WindowAccessor;
import sun.java2d.SurfaceData;
import sun.java2d.opengl.CGLSurfaceData;
import sun.lwawt.*;
......@@ -1057,31 +1061,73 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo
return true;
}
private boolean isOneOfOwnersOrSelf(CPlatformWindow window) {
while (window != null) {
if (this == window) {
return true;
}
window = window.owner;
}
return false;
}
private CPlatformWindow getRootOwner() {
CPlatformWindow rootOwner = this;
while (rootOwner.owner != null) {
rootOwner = rootOwner.owner;
}
return rootOwner;
}
private void orderAboveSiblings() {
if (owner == null) {
return;
// 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();
// 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
owner.execute(nsWindowOwnerPtr->{
execute(nsWindowSelfPtr->{
CWrapper.NSWindow.orderFront(nsWindowOwnerPtr);
CWrapper.NSWindow.orderWindow(nsWindowSelfPtr, CWrapper.NSWindow.NSWindowAbove, nsWindowOwnerPtr);
// 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);
});
});
}
applyWindowLevel(target);
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) {
......
......@@ -4100,6 +4100,10 @@ public class Window extends Container implements Accessible {
public void setTrayIconWindow(Window w, boolean isTrayIconWindow) {
w.isTrayIconWindow = isTrayIconWindow;
}
public Window[] getOwnedWindows(Window w) {
return w.getOwnedWindows_NoClientCode();
}
}); // WindowAccessor
} // static
......
......@@ -334,6 +334,12 @@ public final class AWTAccessor {
* Marks the specified window as an utility window for TrayIcon.
*/
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.
先完成此消息的编辑!
想要评论请 注册