From 5b376db4f09b35f7c561d3a360c96d716cc7b143 Mon Sep 17 00:00:00 2001 From: Alexander Scherbatiy Date: Mon, 16 Sep 2013 17:45:07 +0400 Subject: [PATCH] 8008728: [macosx] Swing. JDialog. Modal dialog goes to background Reviewed-by: serb --- .../sun/lwawt/macosx/CPlatformWindow.java | 5 +- jdk/src/macosx/native/sun/awt/AWTWindow.m | 16 +++ .../ModalDialogOrderingTest.java | 114 ++++++++++++++++++ 3 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 jdk/test/java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index d38946d4376..b85942002fb 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -820,6 +820,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo } nativeSetEnabled(getNSWindowPtr(), !blocked); + checkBlockingAndOrder(); } public final void invalidateShadow(){ @@ -984,7 +985,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo 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 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo 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(); } diff --git a/jdk/src/macosx/native/sun/awt/AWTWindow.m b/jdk/src/macosx/native/sun/awt/AWTWindow.m index 5608b4ad98c..89b0f04640b 100644 --- a/jdk/src/macosx/native/sun/awt/AWTWindow.m +++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m @@ -366,6 +366,22 @@ AWT_ASSERT_APPKIT_THREAD; - (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); } diff --git a/jdk/test/java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java b/jdk/test/java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java new file mode 100644 index 00000000000..e78145e4e12 --- /dev/null +++ b/jdk/test/java/awt/Modal/ModalDialogOrderingTest/ModalDialogOrderingTest.java @@ -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); + } + } +}