--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java Fri Jun 30 11:03:44 2017 +0530
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java Sat Jul 01 09:56:02 2017 +0530
@@ -917,9 +917,14 @@
processMouseEvent(me);
break;
case MouseEvent.MOUSE_WHEEL:
+ // If the scroll is done inside a combobox, menuitem,
+ // or inside a Popup#HeavyWeightWindow or inside a frame
+ // popup should not close which is the standard behaviour
if (isInPopup(src)
- || ((src instanceof JComboBox) && ((JComboBox) src).isPopupVisible())) {
-
+ || ((src instanceof JComboBox) && ((JComboBox) src).isPopupVisible())
+ || ((src instanceof JWindow) && ((JWindow)src).isVisible())
+ || ((src instanceof JMenuItem) && ((JMenuItem)src).isVisible())
+ || (src instanceof JFrame)) {
return;
}
cancelPopupMenu();
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java Fri Jun 30 11:03:44 2017 +0530
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java Sat Jul 01 09:56:02 2017 +0530
@@ -2306,7 +2306,11 @@
if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
grabLog.fine("Generating UngrabEvent on {0} because not inside of shell", this);
}
- postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+ // Do not post Ungrab Event for mouse scroll
+ if ((xbe.get_button() != XConstants.buttons[3])
+ && (xbe.get_button() != XConstants.buttons[4])) {
+ postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+ }
return;
}
}
@@ -2327,14 +2331,26 @@
if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
grabLog.fine("Generating UngrabEvent on {0} because hierarchy ended", this);
}
- postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+ // For mouse wheel event, do not send UngrabEvent
+ if (xbe.get_type() != XConstants.ButtonPress) {
+ postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+ } else if ((xbe.get_button() != XConstants.buttons[3])
+ && (xbe.get_button() != XConstants.buttons[4])) {
+ postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+ }
}
} else {
// toplevel is null - outside of hierarchy
if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
grabLog.fine("Generating UngrabEvent on {0} because toplevel is null", this);
}
- postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+ // For mouse wheel event, do not send UngrabEvent
+ if (xbe.get_type() != XConstants.ButtonPress) {
+ postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+ } else if ((xbe.get_button() != XConstants.buttons[3])
+ && (xbe.get_button() != XConstants.buttons[4])) {
+ postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+ }
return;
}
} else {
@@ -2342,7 +2358,13 @@
if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {
grabLog.fine("Generating UngrabEvent on because target is null {0}", this);
}
- postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+ // For mouse wheel event, do not send UngrabEvent
+ if (xbe.get_type() != XConstants.ButtonPress) {
+ postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+ } else if ((xbe.get_button() != XConstants.buttons[3])
+ && (xbe.get_button() != XConstants.buttons[4])) {
+ postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+ }
return;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JPopupMenu/8075063/ContextMenuScrollTest.java Sat Jul 01 09:56:02 2017 +0530
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2017, 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
+ * @key headful
+ * @bug 8075063
+ * @summary Verifies if Context menu closes on mouse scroll
+ * @run main ContextMenuScrollTest
+ */
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.JSeparator;
+import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
+
+public class ContextMenuScrollTest extends JPopupMenu
+{
+ private JMenuItem undo;
+ private JMenuItem redo;
+ private JMenuItem cut;
+ private JMenuItem copy;
+ private JMenuItem paste;
+ private JMenuItem delete;
+ private JMenuItem selectAll;
+ private final Robot robot;
+ private JFrame frame;
+ private JMenuBar menuBar;
+ private JMenu menu;
+ private volatile Point p = null;
+ private volatile Dimension d = null;
+
+ public static void main(String[] args) throws Exception {
+ new ContextMenuScrollTest();
+ }
+ void blockTillDisplayed(JComponent comp) throws Exception {
+ while (p == null) {
+ try {
+ SwingUtilities.invokeAndWait(() -> {
+ p = comp.getLocationOnScreen();
+ d = menu.getSize();
+ });
+ } catch (IllegalStateException e) {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ie) {
+ }
+ }
+ }
+ }
+
+ public ContextMenuScrollTest() throws Exception
+ {
+ robot = new Robot();
+ robot.setAutoDelay(200);
+ try {
+ SwingUtilities.invokeAndWait(()->createGUI());
+ blockTillDisplayed(menu);
+ robot.waitForIdle();
+
+ robot.mouseMove(p.x + d.width/2, p.y + d.height/2);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ robot.waitForIdle();
+
+ System.out.println("popmenu visible " + menu.isPopupMenuVisible());
+ robot.mouseWheel(1);
+ robot.waitForIdle();
+ System.out.println("popmenu visible " + menu.isPopupMenuVisible());
+ if (!menu.isPopupMenuVisible()) {
+ throw new RuntimeException("Popup closes on mouse scroll");
+ }
+ } finally {
+ SwingUtilities.invokeAndWait(()->frame.dispose());
+ }
+ }
+
+ public void createGUI() {
+ frame = new JFrame();
+ menuBar = new JMenuBar();
+ menu = new JMenu("Menu");
+ menuBar.add(menu);
+
+ undo = new JMenuItem("Undo");
+ undo.setEnabled(false);
+ undo.setAccelerator(KeyStroke.getKeyStroke("control Z"));
+ undo.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent event) {
+ }
+ });
+
+ menu.add(undo);
+
+ redo = new JMenuItem("Redo");
+ redo.setEnabled(false);
+ redo.setAccelerator(KeyStroke.getKeyStroke("control Y"));
+ redo.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent event) {
+ }
+ });
+ menu.add(redo);
+
+ menu.add(new JSeparator());
+
+ cut = new JMenuItem("Cut");
+ cut.setEnabled(false);
+ cut.setAccelerator(KeyStroke.getKeyStroke("control X"));
+ cut.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent event) {
+ }
+ });
+
+ menu.add(cut);
+
+ copy = new JMenuItem("Copy");
+ copy.setEnabled(false);
+ copy.setAccelerator(KeyStroke.getKeyStroke("control C"));
+ copy.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent event) {
+ }
+ });
+
+ menu.add(copy);
+
+ paste = new JMenuItem("Paste");
+ paste.setEnabled(false);
+ paste.setAccelerator(KeyStroke.getKeyStroke("control V"));
+ paste.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent event) {
+ }
+ });
+
+ menu.add(paste);
+
+ delete = new JMenuItem("Delete");
+ delete.setEnabled(false);
+ delete.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
+ delete.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent event) {
+ }
+ });
+
+ menu.add(delete);
+
+ menu.add(new JSeparator());
+
+ selectAll = new JMenuItem("Select All");
+ selectAll.setEnabled(false);
+ selectAll.setAccelerator(KeyStroke.getKeyStroke("control A"));
+ selectAll.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent event) {
+ }
+ });
+ menu.add(selectAll);
+ frame.setJMenuBar(menuBar);
+
+ frame.pack();
+ frame.setVisible(true);
+ }
+}