8032872: [macosx] Cannot select from JComboBox in a JWindow
authordmarkov
Thu, 06 Mar 2014 17:13:55 +0400
changeset 23627 f578c6ea3c8d
parent 23626 4494f1fd1f57
child 23628 158574ce42ec
8032872: [macosx] Cannot select from JComboBox in a JWindow Reviewed-by: pchelko, ant
jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java
jdk/test/java/awt/Mouse/MouseComboBoxTest/MouseComboBoxTest.java
jdk/test/java/awt/Window/Grab/GrabTest.java
--- 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.");