8187803: JDK part of JavaFX-Swing dialogs appearing behind main stage
Reviewed-by: kcr, serb, ssadetsky
--- a/src/java.desktop/macosx/classes/sun/lwawt/LWLightweightFramePeer.java Wed Nov 08 12:34:59 2017 -0800
+++ b/src/java.desktop/macosx/classes/sun/lwawt/LWLightweightFramePeer.java Thu Nov 09 11:27:13 2017 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,11 @@
import java.awt.event.FocusEvent;
import sun.awt.LightweightFrame;
+import sun.awt.OverrideNativeWindowHandle;
import sun.swing.JLightweightFrame;
import sun.swing.SwingAccessor;
-public class LWLightweightFramePeer extends LWWindowPeer {
+public class LWLightweightFramePeer extends LWWindowPeer implements OverrideNativeWindowHandle {
public LWLightweightFramePeer(LightweightFrame target,
PlatformComponent platformComponent,
@@ -116,4 +117,16 @@
public void updateCursorImmediately() {
SwingAccessor.getJLightweightFrameAccessor().updateCursor((JLightweightFrame)getLwTarget());
}
+
+ // SwingNode
+ private volatile long overriddenWindowHandle = 0L;
+
+ @Override
+ public void overrideWindowHandle(final long handle) {
+ this.overriddenWindowHandle = handle;
+ }
+
+ public long getOverriddenWindowHandle() {
+ return overriddenWindowHandle;
+ }
}
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Wed Nov 08 12:34:59 2017 -0800
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Thu Nov 09 11:27:13 2017 +0530
@@ -63,6 +63,7 @@
import sun.awt.AWTAccessor.WindowAccessor;
import sun.java2d.SurfaceData;
import sun.java2d.opengl.CGLSurfaceData;
+import sun.lwawt.LWLightweightFramePeer;
import sun.lwawt.LWToolkit;
import sun.lwawt.LWWindowPeer;
import sun.lwawt.LWWindowPeer.PeerType;
@@ -637,6 +638,20 @@
if (!isKeyWindow) {
CWrapper.NSWindow.makeKeyWindow(ptr);
}
+
+ if (owner != null
+ && owner.getPeer() instanceof LWLightweightFramePeer) {
+ LWLightweightFramePeer peer =
+ (LWLightweightFramePeer) owner.getPeer();
+
+ long ownerWindowPtr = peer.getOverriddenWindowHandle();
+ if (ownerWindowPtr != 0) {
+ //Place window above JavaFX stage
+ CWrapper.NSWindow.addChildWindow(
+ ownerWindowPtr, ptr,
+ CWrapper.NSWindow.NSWindowAbove);
+ }
+ }
});
} else {
execute(ptr->{
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.desktop/share/classes/sun/awt/OverrideNativeWindowHandle.java Thu Nov 09 11:27:13 2017 +0530
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.awt;
+
+/**
+ * Used for replacing window owner with another non-Swing window.
+ * It is useful in case of JavaFX-Swing interop:
+ * it helps to keep Swing dialogs above its owner(JavaFX stage).
+ */
+
+public interface OverrideNativeWindowHandle {
+
+ /**
+ * Replaces an owner window with a window with provided handle.
+ * @param handle native window handle
+ */
+ void overrideWindowHandle(final long handle);
+}
--- a/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java Wed Nov 08 12:34:59 2017 -0800
+++ b/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java Thu Nov 09 11:27:13 2017 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -54,6 +54,7 @@
import sun.awt.AWTAccessor;
import sun.awt.DisplayChangedListener;
import sun.awt.LightweightFrame;
+import sun.awt.OverrideNativeWindowHandle;
import sun.security.action.GetPropertyAction;
import sun.swing.SwingUtilities2.RepaintListener;
@@ -526,6 +527,18 @@
}
}
+ //Called by reflection by SwingNode
+ public void overrideNativeWindowHandle(long handle, Runnable closeWindow) {
+ final Object peer = AWTAccessor.getComponentAccessor().getPeer(this);
+ if (peer instanceof OverrideNativeWindowHandle) {
+ ((OverrideNativeWindowHandle) peer).overrideWindowHandle(handle);
+ }
+ if (closeWindow != null) {
+ closeWindow.run();
+ }
+ }
+
+
public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
Class<T> abstractRecognizerClass,
DragSource ds, Component c, int srcActions,
--- a/src/java.desktop/unix/classes/sun/awt/X11/XLightweightFramePeer.java Wed Nov 08 12:34:59 2017 -0800
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XLightweightFramePeer.java Thu Nov 09 11:27:13 2017 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,10 +29,11 @@
import java.awt.dnd.DropTarget;
import sun.awt.LightweightFrame;
+import sun.awt.OverrideNativeWindowHandle;
import sun.swing.JLightweightFrame;
import sun.swing.SwingAccessor;
-public class XLightweightFramePeer extends XFramePeer {
+public class XLightweightFramePeer extends XFramePeer implements OverrideNativeWindowHandle {
XLightweightFramePeer(LightweightFrame target) {
super(target);
@@ -80,4 +81,15 @@
public void removeDropTarget(DropTarget dt) {
getLwTarget().removeDropTarget(dt);
}
+
+ private volatile long overriddenWindowHandle = 0L;
+
+ @Override
+ public void overrideWindowHandle(final long handle) {
+ overriddenWindowHandle = handle;
+ }
+
+ public long getOverriddenWindowHandle() {
+ return overriddenWindowHandle;
+ }
}
--- a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java Wed Nov 08 12:34:59 2017 -0800
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java Thu Nov 09 11:27:13 2017 +0530
@@ -1695,6 +1695,14 @@
tpw = XlibUtil.getParentWindow(tpw);
parent = XToolkit.windowToXWindow(tpw);
}
+
+ if (parent instanceof XLightweightFramePeer) {
+ XLightweightFramePeer peer = (XLightweightFramePeer) parent;
+ long ownerWindowPtr = peer.getOverriddenWindowHandle();
+ if (ownerWindowPtr != 0) {
+ tpw = ownerWindowPtr;
+ }
+ }
XlibWrapper.XSetTransientFor(XToolkit.getDisplay(), bpw, tpw);
window.curRealTransientFor = parent;
}
--- a/src/java.desktop/windows/classes/sun/awt/windows/WLightweightFramePeer.java Wed Nov 08 12:34:59 2017 -0800
+++ b/src/java.desktop/windows/classes/sun/awt/windows/WLightweightFramePeer.java Thu Nov 09 11:27:13 2017 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,10 +32,11 @@
import java.awt.event.MouseEvent;
import sun.awt.LightweightFrame;
+import sun.awt.OverrideNativeWindowHandle;
import sun.swing.JLightweightFrame;
import sun.swing.SwingAccessor;
-public class WLightweightFramePeer extends WFramePeer {
+public class WLightweightFramePeer extends WFramePeer implements OverrideNativeWindowHandle {
public WLightweightFramePeer(LightweightFrame target) {
super(target);
@@ -50,6 +51,13 @@
return getLwTarget().getGraphics();
}
+ private native void overrideNativeHandle(long hwnd);
+
+ @Override
+ public void overrideWindowHandle(final long handle) {
+ overrideNativeHandle(handle);
+ }
+
@Override
public void show() {
super.show();
--- a/src/java.desktop/windows/native/libawt/windows/awt_Dialog.cpp Wed Nov 08 12:34:59 2017 -0800
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Dialog.cpp Thu Nov 09 11:27:13 2017 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -118,7 +118,8 @@
if (parent != NULL) {
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtWindow *)pData;
- hwndParent = awtParent->GetHWnd();
+ HWND oHWnd = awtParent->GetOverriddenHWnd();
+ hwndParent = oHWnd ? oHWnd : awtParent->GetHWnd();
} else {
// There is no way to prevent a parentless dialog from showing on
// the taskbar other than to specify an invisible parent and set
--- a/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp Wed Nov 08 12:34:59 2017 -0800
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp Thu Nov 09 11:27:13 2017 +0530
@@ -169,7 +169,8 @@
JNI_CHECK_PEER_GOTO(parent, done);
{
AwtFrame* parent = (AwtFrame *)pData;
- hwndParent = parent->GetHWnd();
+ HWND oHWnd = parent->GetOverriddenHWnd();
+ hwndParent = oHWnd ? oHWnd : parent->GetHWnd();
}
}
--- a/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp Wed Nov 08 12:34:59 2017 -0800
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp Thu Nov 09 11:27:13 2017 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -164,6 +164,11 @@
jfloat scaleY;
};
+struct OverrideHandle {
+ jobject frame;
+ HWND handle;
+};
+
/************************************************************************
* AwtWindow fields
*/
@@ -242,6 +247,7 @@
prevScaleRec.screen = -1;
prevScaleRec.scaleX = -1.0f;
prevScaleRec.scaleY = -1.0f;
+ m_overriddenHwnd = NULL;
}
AwtWindow::~AwtWindow()
@@ -2571,6 +2577,24 @@
delete rfs;
}
+void AwtWindow::_OverrideHandle(void *param)
+{
+ JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+ OverrideHandle* oh = (OverrideHandle *) param;
+ jobject self = oh->frame;
+ AwtWindow *f = NULL;
+
+ PDATA pData;
+ JNI_CHECK_PEER_GOTO(self, ret);
+ f = (AwtWindow *)pData;
+ f->OverrideHWnd(oh->handle);
+ret:
+ env->DeleteGlobalRef(self);
+
+ delete oh;
+}
+
/*
* This is AwtWindow-specific function that is not intended for reusing
*/
@@ -3946,4 +3970,25 @@
CATCH_BAD_ALLOC;
}
+
+/*
+ * Class: sun_awt_windows_WLightweightFramePeer
+ * Method: overrideNativeHandle
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_sun_awt_windows_WLightweightFramePeer_overrideNativeHandle
+ (JNIEnv *env, jobject self, jlong hwnd)
+{
+ TRY;
+
+ OverrideHandle *oh = new OverrideHandle;
+ oh->frame = env->NewGlobalRef(self);
+ oh->handle = (HWND) hwnd;
+
+ AwtToolkit::GetInstance().SyncCall(AwtFrame::_OverrideHandle, oh);
+ // global ref and oh are deleted in _OverrideHandle()
+
+ CATCH_BAD_ALLOC;
+}
+
} /* extern "C" */
--- a/src/java.desktop/windows/native/libawt/windows/awt_Window.h Wed Nov 08 12:34:59 2017 -0800
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Window.h Thu Nov 09 11:27:13 2017 +0530
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -245,6 +245,7 @@
static void _SetFullScreenExclusiveModeState(void* param);
static void _GetNativeWindowSize(void* param);
static void _WindowDPIChange(void* param);
+ static void _OverrideHandle(void *param);
inline static BOOL IsResizing() {
return sm_resizing;
@@ -260,6 +261,9 @@
static void FocusedWindowChanged(HWND from, HWND to);
+ inline HWND GetOverriddenHWnd() { return m_overriddenHwnd; }
+ inline void OverrideHWnd(HWND hwnd) { m_overriddenHwnd = hwnd; }
+
private:
static int ms_instanceCounter;
static HHOOK ms_hCBTFilter;
@@ -311,6 +315,9 @@
// The tooltip that appears when hovering the icon
HWND securityTooltipWindow;
+ //Allows substitute parent window with JavaFX stage to make it below a dialog
+ HWND m_overriddenHwnd;
+
UINT warningWindowWidth;
UINT warningWindowHeight;
void InitSecurityWarningSize(JNIEnv *env);