# HG changeset patch # User anashaty # Date 1425649134 -10800 # Node ID b56181e8ad3c6e41f2f65e03cf95cfe903676675 # Parent 973914c573fc997d54e44dc718844eac2a8b4684 8072900: Mouse events are captured by the wrong menu in OS X Reviewed-by: serb, alexp diff -r 973914c573fc -r b56181e8ad3c jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaMenuUI.java --- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaMenuUI.java Thu Mar 05 11:07:48 2015 +0300 +++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaMenuUI.java Fri Mar 06 16:38:54 2015 +0300 @@ -148,11 +148,15 @@ // In Aqua, we always have a menu delay, regardless of where the menu is. if (!(selectedPath.length > 0 && selectedPath[selectedPath.length - 1] == menu.getPopupMenu())) { - if (menu.getDelay() == 0) { - appendPath(getPath(), menu.getPopupMenu()); - } else { - manager.setSelectedPath(getPath()); - setupPostTimer(menu); + // the condition below prevents from activating menu in other frame + if (!menu.isTopLevelMenu() || (selectedPath.length > 0 && + selectedPath[0] == menu.getParent())) { + if (menu.getDelay() == 0) { + appendPath(getPath(), menu.getPopupMenu()); + } else { + manager.setSelectedPath(getPath()); + setupPostTimer(menu); + } } } } diff -r 973914c573fc -r b56181e8ad3c jdk/test/javax/swing/JMenu/8072900/WrongSelectionOnMouseOver.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/swing/JMenu/8072900/WrongSelectionOnMouseOver.java Fri Mar 06 16:38:54 2015 +0300 @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2015, 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 8072900 +@summary Mouse events are captured by the wrong menu in OS X +@author Anton Nashatyrev +@run main WrongSelectionOnMouseOver +*/ + +import javax.swing.*; +import javax.swing.event.MenuEvent; +import javax.swing.event.MenuListener; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static javax.swing.UIManager.getInstalledLookAndFeels; + +public class WrongSelectionOnMouseOver implements Runnable { + + CountDownLatch firstMenuSelected = new CountDownLatch(1); + CountDownLatch secondMenuMouseEntered = new CountDownLatch(1); + CountDownLatch secondMenuSelected = new CountDownLatch(1); + + JMenu m1, m2; + + private UIManager.LookAndFeelInfo laf; + JFrame frame1; + JFrame frame2; + + public WrongSelectionOnMouseOver(UIManager.LookAndFeelInfo laf) throws Exception { + this.laf = laf; + } + + private void createUI() throws Exception { + System.out.println("Testing UI: " + laf); + UIManager.setLookAndFeel(laf.getClassName()); + + { + frame1 = new JFrame("Frame1"); + JMenuBar mb = new JMenuBar(); + m1 = new JMenu("File"); + JMenuItem i1 = new JMenuItem("Save"); + JMenuItem i2 = new JMenuItem("Load"); + + m1.addMenuListener(new MenuListener() { + @Override + public void menuSelected(MenuEvent e) { + firstMenuSelected.countDown(); + System.out.println("Menu1: menuSelected"); + } + + @Override + public void menuDeselected(MenuEvent e) { + System.out.println("Menu1: menuDeselected"); + } + + @Override + public void menuCanceled(MenuEvent e) { + System.out.println("Menu1: menuCanceled"); + } + }); + + frame1.setJMenuBar(mb); + mb.add(m1); + m1.add(i1); + m1.add(i2); + + frame1.setLayout(new FlowLayout()); + frame1.setBounds(200, 200, 200, 200); + + frame1.setVisible(true); + } + + { + frame2 = new JFrame("Frame2"); + JMenuBar mb = new JMenuBar(); + m2 = new JMenu("File"); + JMenuItem i1 = new JMenuItem("Save"); + JMenuItem i2 = new JMenuItem("Load"); + + m2.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + secondMenuMouseEntered.countDown(); + System.out.println("WrongSelectionOnMouseOver.mouseEntered"); + } + }); + + m2.addMenuListener(new MenuListener() { + @Override + public void menuSelected(MenuEvent e) { + secondMenuSelected.countDown(); + System.out.println("Menu2: menuSelected"); + } + + @Override + public void menuDeselected(MenuEvent e) { + System.out.println("Menu2: menuDeselected"); + } + + @Override + public void menuCanceled(MenuEvent e) { + System.out.println("Menu2: menuCanceled"); + } + }); + + frame2.setJMenuBar(mb); + mb.add(m2); + m2.add(i1); + m2.add(i2); + + frame2.setLayout(new FlowLayout()); + frame2.setBounds(400, 200, 200, 200); + + frame2.setVisible(true); + } + } + + public void disposeUI() { + frame1.dispose(); + frame2.dispose(); + } + + @Override + public void run() { + try { + if (frame1 == null) { + createUI(); + } else { + disposeUI(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public void test() throws Exception { + Robot robot = new Robot(); + robot.setAutoDelay(100); + + robot.waitForIdle(); + + robot.mouseMove((int) m1.getLocationOnScreen().getX() + 5, + (int) m1.getLocationOnScreen().getY() + 5); + robot.mousePress(MouseEvent.BUTTON1_MASK); + robot.mouseRelease(MouseEvent.BUTTON1_MASK); + + if (!firstMenuSelected.await(5, TimeUnit.SECONDS)) { + throw new RuntimeException("Menu has not been selected."); + }; + + robot.mouseMove((int) m2.getLocationOnScreen().getX() + 5, + (int) m2.getLocationOnScreen().getY() + 5); + + if (!secondMenuMouseEntered.await(5, TimeUnit.SECONDS)) { + throw new RuntimeException("MouseEntered event missed for the second menu"); + }; + + if (secondMenuSelected.await(1, TimeUnit.SECONDS)) { + throw new RuntimeException("The second menu has been selected"); + }; + } + + public static void main(final String[] args) throws Exception { + for (final UIManager.LookAndFeelInfo laf : getInstalledLookAndFeels()) { + WrongSelectionOnMouseOver test = new WrongSelectionOnMouseOver(laf); + SwingUtilities.invokeAndWait(test); + test.test(); + SwingUtilities.invokeAndWait(test); + } + System.out.println("Test passed"); + } +} \ No newline at end of file