From b697b48a0133458983caea4acc6de8de3e56d356 Mon Sep 17 00:00:00 2001 From: Alisen Chung Date: Wed, 12 Jun 2024 18:44:07 +0000 Subject: [PATCH] 8315655: [macos] Right click and dragging over a component with a popup menu will open the popup Reviewed-by: dnguyen, psadhukhan --- .../sun/lwawt/macosx/CPlatformResponder.java | 4 +- .../classes/sun/lwawt/macosx/CTrayIcon.java | 2 +- .../classes/sun/lwawt/macosx/NSEvent.java | 9 +- .../swing/JPopupMenu/MouseDragPopupTest.java | 129 ++++++++++++++++++ 4 files changed, 139 insertions(+), 5 deletions(-) create mode 100644 test/jdk/javax/swing/JPopupMenu/MouseDragPopupTest.java diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java index f14c7b40cba..0501bbfab03 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, 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 @@ -87,7 +87,7 @@ final class CPlatformResponder { jmodifiers |= MouseEvent.getMaskForButton(jbuttonNumber); } - boolean jpopupTrigger = NSEvent.isPopupTrigger(jmodifiers); + boolean jpopupTrigger = NSEvent.isPopupTrigger(jmodifiers, jeventType); eventNotifier.notifyMouseEvent(jeventType, System.currentTimeMillis(), jbuttonNumber, x, y, absX, absY, jmodifiers, jclickCount, diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java index d0b9288aeae..7d35f859a7a 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java @@ -253,7 +253,7 @@ public class CTrayIcon extends CFRetainedResource implements TrayIconPeer { int jmodifiers = NSEvent.nsToJavaModifiers( nsEvent.getModifierFlags()); - boolean isPopupTrigger = NSEvent.isPopupTrigger(jmodifiers); + boolean isPopupTrigger = NSEvent.isPopupTrigger(jmodifiers, jeventType); int eventButtonMask = (jbuttonNumber > 0)? MouseEvent.getMaskForButton(jbuttonNumber) : 0; diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSEvent.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSEvent.java index ca3d9ad5da7..f3fcfdfb43c 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSEvent.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/NSEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, 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 @@ -269,7 +269,12 @@ final class NSEvent { */ static native char nsToJavaChar(char nsChar, int modifierFlags, boolean spaceKeyTyped); - static boolean isPopupTrigger(int jmodifiers) { + static boolean isPopupTrigger(int jmodifiers, int jeventType) { + if (jeventType != MouseEvent.MOUSE_PRESSED + && jeventType != MouseEvent.MOUSE_RELEASED) { + return false; + } + final boolean isRightButtonDown = ((jmodifiers & InputEvent.BUTTON3_DOWN_MASK) != 0); final boolean isLeftButtonDown = ((jmodifiers & InputEvent.BUTTON1_DOWN_MASK) != 0); final boolean isControlDown = ((jmodifiers & InputEvent.CTRL_DOWN_MASK) != 0); diff --git a/test/jdk/javax/swing/JPopupMenu/MouseDragPopupTest.java b/test/jdk/javax/swing/JPopupMenu/MouseDragPopupTest.java new file mode 100644 index 00000000000..e34b53d0360 --- /dev/null +++ b/test/jdk/javax/swing/JPopupMenu/MouseDragPopupTest.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2024, 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.Dimension; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.InputEvent; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; + +/* + * @test + * @bug 8315655 + * @summary Verifies Right click and dragging over a component with a popup menu will not open the popup + * @key headful + * @run main MouseDragPopupTest + */ +public class MouseDragPopupTest { + static JFrame frame; + static JPanel panel; + static Robot robot; + static volatile boolean failed; + static volatile Point srcPoint; + static volatile Dimension d; + + public static void main(String[] args) throws Exception { + try { + robot = new Robot(); + robot.setAutoWaitForIdle(true); + robot.setAutoDelay(100); + + SwingUtilities.invokeAndWait(() -> { + createAndShowGUI(); + }); + robot.delay(1000); + + SwingUtilities.invokeAndWait(() -> { + srcPoint = frame.getLocationOnScreen(); + d = frame.getSize(); + }); + srcPoint.translate(2 * d.width / 3, 3 * d.height / 4); + + final Point dstPoint = new Point(srcPoint); + dstPoint.translate(4 * d.width / 15, 0); + + robot.mouseMove(srcPoint.x, srcPoint.y); + + robot.mousePress(InputEvent.BUTTON3_DOWN_MASK); + + while (!srcPoint.equals(dstPoint)) { + srcPoint.translate(sign(dstPoint.x - srcPoint.x), 0); + robot.mouseMove(srcPoint.x, srcPoint.y); + } + + if (failed) { + throw new RuntimeException("Popup was shown, Test Failed."); + } + } finally { + robot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); + SwingUtilities.invokeAndWait(() -> { + if (frame != null) { + frame.dispose(); + } + }); + } + } + + public static int sign(int n) { + return n < 0 ? -1 : n == 0 ? 0 : 1; + } + + static void createAndShowGUI() { + frame = new JFrame("MouseDragPopupTest"); + panel = new JPanel(); + JPanel innerPanel = new JPanel(); + JPopupMenu menu = new JPopupMenu(); + + menu.addPopupMenuListener(new PopupMenuListener() { + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + failed = true; + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {} + + @Override + public void popupMenuCanceled(PopupMenuEvent e) {} + }); + + menu.add("This should not appear"); + innerPanel.setComponentPopupMenu(menu); + + panel.add(new JLabel("Right click and drag from here")); + panel.add(innerPanel); + panel.add(new JLabel("to here")); + + frame.add(panel); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } +}