8032872: [macosx] Cannot select from JComboBox in a JWindow
Reviewed-by: pchelko, ant
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Thu Mar 06 15:29:23 2014 +0400
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Thu Mar 06 17:13:55 2014 +0400
@@ -685,7 +685,7 @@
public void notifyNCMouseDown() {
// Ungrab except for a click on a Dialog with the grabbing owner
if (grabbingWindow != null &&
- grabbingWindow != getOwnerFrameDialog(this))
+ !grabbingWindow.isOneOfOwnersOf(this))
{
grabbingWindow.ungrab();
}
@@ -780,7 +780,7 @@
// Ungrab only if this window is not an owned window of the grabbing one.
if (!isGrabbing() && grabbingWindow != null &&
- grabbingWindow != getOwnerFrameDialog(this))
+ !grabbingWindow.isOneOfOwnersOf(this))
{
grabbingWindow.ungrab();
}
@@ -1235,6 +1235,17 @@
changeFocusedWindow(activate, null);
}
+ private boolean isOneOfOwnersOf(LWWindowPeer peer) {
+ Window owner = (peer != null ? peer.getTarget().getOwner() : null);
+ while (owner != null) {
+ if ((LWWindowPeer)owner.getPeer() == this) {
+ return true;
+ }
+ owner = owner.getOwner();
+ }
+ return false;
+ }
+
/*
* Changes focused window on java level.
*/
@@ -1266,7 +1277,7 @@
// - when the opposite (gaining focus) window is an owned/owner window.
// - for a simple window in any case.
if (!becomesFocused &&
- (isGrabbing() || getOwnerFrameDialog(grabbingWindow) == this))
+ (isGrabbing() || this.isOneOfOwnersOf(grabbingWindow)))
{
if (focusLog.isLoggable(PlatformLogger.Level.FINE)) {
focusLog.fine("ungrabbing on " + grabbingWindow);
@@ -1285,6 +1296,11 @@
postEvent(windowEvent);
}
+ /*
+ * Retrieves the owner of the peer.
+ * Note: this method returns the owner which can be activated, (i.e. the instance
+ * of Frame or Dialog may be returned).
+ */
static LWWindowPeer getOwnerFrameDialog(LWWindowPeer peer) {
Window owner = (peer != null ? peer.getTarget().getOwner() : null);
while (owner != null && !(owner instanceof Frame || owner instanceof Dialog)) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Mouse/MouseComboBoxTest/MouseComboBoxTest.java Thu Mar 06 17:13:55 2014 +0400
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+
+/*
+ * @test
+ * @bug 8032872
+ * @summary Tests JComboBox selection via the mouse
+ * @author Dmitry Markov
+ */
+import sun.awt.SunToolkit;
+
+import javax.swing.*;
+import javax.swing.plaf.basic.BasicComboPopup;
+import javax.swing.plaf.basic.ComboPopup;
+import javax.swing.plaf.metal.MetalComboBoxUI;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+import java.awt.*;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+
+public class MouseComboBoxTest {
+ private static final String[] items = {"One", "Two", "Three", "Four", "Five"};
+
+ private static SunToolkit toolkit = null;
+ private static Robot robot = null;
+ private static JFrame frame = null;
+ private static JComboBox comboBox = null;
+ private static MyComboBoxUI comboBoxUI = null;
+
+ public static void main(String[] args) throws Exception {
+ toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+ robot = new Robot();
+ robot.setAutoDelay(50);
+
+ UIManager.setLookAndFeel(new MetalLookAndFeel());
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ createAndShowGUI();
+ }
+ });
+ toolkit.realSync();
+
+ for (int i = 0; i < items.length; i++) {
+ // Open popup
+ robot.keyPress(KeyEvent.VK_DOWN);
+ robot.keyRelease(KeyEvent.VK_DOWN);
+ toolkit.realSync();
+
+ Point point = getItemPointToClick(i);
+ robot.mouseMove(point.x, point.y);
+ robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+ toolkit.realSync();
+
+ if (i != getSelectedIndex()) {
+ throw new RuntimeException("Test Failed! Incorrect value of selected index = " + getSelectedIndex() +
+ ", expected value = " + i);
+ }
+ }
+ }
+
+ private static Point getItemPointToClick(final int item) throws Exception {
+ final Point[] result = new Point[1];
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ BasicComboPopup popup = (BasicComboPopup)comboBoxUI.getComboPopup();
+ Point point = popup.getLocationOnScreen();
+ Dimension size = popup.getSize();
+
+ int step = size.height / items.length;
+ point.x += size.width / 2;
+ point.y += step / 2 + step * item;
+ result[0] = point;
+ }
+ });
+ return result[0];
+ }
+
+ private static int getSelectedIndex() throws Exception {
+ final int[] result = new int[1];
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ result[0] = comboBox.getSelectedIndex();
+ }
+ });
+ return result[0];
+ }
+
+ private static void createAndShowGUI() {
+ frame = new JFrame("MouseComboBoxTest");
+
+ comboBox = new JComboBox(items);
+ comboBox.setEditable(true);
+ comboBoxUI = new MyComboBoxUI();
+ comboBox.setUI(comboBoxUI);
+
+ frame.pack();
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setVisible(true);
+
+ JWindow window = new JWindow(frame);
+ window.add(comboBox);
+ window.pack();
+ window.setVisible(true);
+ }
+
+ private static class MyComboBoxUI extends MetalComboBoxUI {
+ public ComboPopup getComboPopup() {
+ return popup;
+ }
+ }
+}
+
--- a/jdk/test/java/awt/Window/Grab/GrabTest.java Thu Mar 06 15:29:23 2014 +0400
+++ b/jdk/test/java/awt/Window/Grab/GrabTest.java Thu Mar 06 17:13:55 2014 +0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, 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
@@ -38,7 +38,10 @@
public class GrabTest {
private static Frame f;
private static Frame f1;
+ private static Frame frame;
private static Window w;
+ private static Window window1;
+ private static Window window2;
private static Button b;
private static Robot robot;
@@ -96,6 +99,15 @@
f.setVisible(true);
w.setVisible(true);
+ frame = new Frame();
+ window1 = new Window(frame);
+ window1.setBounds(0, 0, 100, 100);
+ window1.setBackground(Color.blue);
+
+ window2 = new Window(window1);
+ window2.setBounds(0, 0, 50, 50);
+ window2.setBackground(Color.green);
+
tk = (sun.awt.SunToolkit)Toolkit.getDefaultToolkit();
try {
@@ -194,6 +206,24 @@
passed = false;
System.err.println("Failure: [7] Window disposal didn't cause ungrab");
}
+ ungrabbed = false;
+
+
+ // 8. Check that mouse click on subwindow does not cause ungrab
+ frame.setVisible(true);
+ window1.setVisible(true);
+ window2.setVisible(true);
+ Util.waitForIdle(robot);
+
+ tk.grab(window1);
+
+ Util.clickOnComp(window2, robot);
+ Util.waitForIdle(robot);
+
+ if (ungrabbed) {
+ passed = false;
+ System.err.println("Failure: [8] Press on the subwindow caused ungrab");
+ }
if (passed) {
System.out.println("Test passed.");