8008728: [macosx] Swing. JDialog. Modal dialog goes to background
Reviewed-by: serb
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Sep 13 18:02:18 2013 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Mon Sep 16 17:45:07 2013 +0400
@@ -820,6 +820,7 @@
}
nativeSetEnabled(getNSWindowPtr(), !blocked);
+ checkBlockingAndOrder();
}
public final void invalidateShadow(){
@@ -984,7 +985,7 @@
setStyleBits(SHOULD_BECOME_KEY | SHOULD_BECOME_MAIN, isFocusable); // set both bits at once
}
- private boolean checkBlocking() {
+ private boolean checkBlockingAndOrder() {
LWWindowPeer blocker = (peer == null)? null : peer.getBlocker();
if (blocker == null) {
return false;
@@ -1040,7 +1041,7 @@
private void windowDidBecomeMain() {
assert CThreading.assertAppKit();
- if (checkBlocking()) return;
+ if (checkBlockingAndOrder()) return;
// If it's not blocked, make sure it's above its siblings
orderAboveSiblings();
}
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m Fri Sep 13 18:02:18 2013 +0400
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m Mon Sep 16 17:45:07 2013 +0400
@@ -366,6 +366,22 @@
- (BOOL) canBecomeMainWindow {
AWT_ASSERT_APPKIT_THREAD;
+ if(!self.isEnabled){
+ // Native system can bring up the NSWindow to
+ // the top even if the window is not main.
+ // We should bring up the modal dialog manually
+ [AWTToolkit eventCountPlusPlus];
+
+ JNIEnv *env = [ThreadUtilities getJNIEnv];
+ jobject platformWindow = [self.javaPlatformWindow jObjectWithEnv:env];
+ if (platformWindow != NULL) {
+ static JNF_MEMBER_CACHE(jm_checkBlockingAndOrder, jc_CPlatformWindow,
+ "checkBlockingAndOrder", "()Z");
+ JNFCallVoidMethod(env, platformWindow, jm_checkBlockingAndOrder);
+ (*env)->DeleteLocalRef(env, platformWindow);
+ }
+ }
+
return self.isEnabled && IS(self.styleBits, SHOULD_BECOME_MAIN);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java Mon Sep 16 17:45:07 2013 +0400
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2011, 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.
+ *
+ * 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.
+ */
+
+import java.awt.Color;
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.event.InputEvent;
+import sun.awt.SunToolkit;
+/*
+ * @test
+ * @bug 8008728
+ * @summary [macosx] Swing. JDialog. Modal dialog goes to background
+ * @author Alexandr Scherbatiy
+ * @run main ModalDialogOrderingTest
+ */
+
+public class ModalDialogOrderingTest {
+
+ private static final Color DIALOG_COLOR = Color.GREEN;
+ private static final Color FRAME_COLOR = Color.BLUE;
+
+ public static void main(String[] args) {
+
+ final Frame frame = new Frame("Test");
+ frame.setSize(100, 100);
+ frame.setBackground(FRAME_COLOR);
+ frame.setVisible(true);
+
+ final Dialog modalDialog = new Dialog((Frame) null, true);
+ modalDialog.setTitle("Modal Dialog");
+ modalDialog.setSize(50, 50);
+ modalDialog.setBackground(DIALOG_COLOR);
+ modalDialog.setModal(true);
+
+ new Thread(new Runnable() {
+
+ @Override
+ public void run() {
+ runTest(modalDialog, frame);
+ }
+ }).start();
+
+ modalDialog.setVisible(true);
+ }
+
+ private static void runTest(Dialog dialog, Frame frame) {
+ try {
+ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+ Robot robot = new Robot();
+ robot.setAutoDelay(15);
+ robot.mouseMove(300, 300);
+
+ while (!dialog.isVisible()) {
+ toolkit.realSync();
+ }
+
+ Rectangle dialogBounds = dialog.getBounds();
+ Rectangle frameBounds = frame.getBounds();
+
+ double x0 = dialogBounds.getX();
+ double y0 = dialogBounds.getY();
+ double x1 = dialogBounds.getX() + dialogBounds.getWidth();
+ double y1 = dialogBounds.getY() + dialogBounds.getHeight();
+ double x2 = frameBounds.getX() + frameBounds.getWidth();
+ double y2 = frameBounds.getY() + frameBounds.getHeight();
+
+ int clickX = (int) ((x2 + x1) / 2);
+ int clickY = (int) ((y2 + y1) / 2);
+
+ robot.mouseMove(clickX, clickY);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ toolkit.realSync();
+
+ int colorX = (int) ((x0 + x1) / 2);
+ int colorY = (int) ((y0 + y1) / 2);
+
+ Color color = robot.getPixelColor(colorX, colorY);
+
+ dialog.setVisible(false);
+ frame.setVisible(false);
+
+ if (!DIALOG_COLOR.equals(color)) {
+ throw new RuntimeException("The frame is on top"
+ + " of the modal dialog!");
+ }
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}