8187803: JDK part of JavaFX-Swing dialogs appearing behind main stage
authorazvegint
Thu, 09 Nov 2017 11:27:13 +0530
changeset 47827 f2238a5326e7
parent 47720 79efc2c3d832
child 47828 8a3c1bdf9ecb
8187803: JDK part of JavaFX-Swing dialogs appearing behind main stage Reviewed-by: kcr, serb, ssadetsky
src/java.desktop/macosx/classes/sun/lwawt/LWLightweightFramePeer.java
src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
src/java.desktop/share/classes/sun/awt/OverrideNativeWindowHandle.java
src/java.desktop/share/classes/sun/swing/JLightweightFrame.java
src/java.desktop/unix/classes/sun/awt/X11/XLightweightFramePeer.java
src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java
src/java.desktop/windows/classes/sun/awt/windows/WLightweightFramePeer.java
src/java.desktop/windows/native/libawt/windows/awt_Dialog.cpp
src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp
src/java.desktop/windows/native/libawt/windows/awt_Window.cpp
src/java.desktop/windows/native/libawt/windows/awt_Window.h
--- 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);