Could you please review this fix again?
There's no changes in fix, but test was added.
Webrev:
http://cr.openjdk.java.net/~alexp/8001633/webrev.02/ <http://cr.openjdk.java.net/%7Ealexp/8001633/webrev.02/>

On 10/29/2012 2:23 PM, Mikhail Cherkasov wrote:
Hi all,

Could you please review a fix for 8001633 <http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8001633>: Wrong alt processing during switching between windows. Bug:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8001633 <http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8001633>
Webrev:
http://cr.openjdk.java.net/~bagiras/8/7082294.1/

To prevent wrong focus traversing to menu was added additional check to AltProcessor. It checks that original source of 'alt' event belongs to AltProcessor.winAncestor
or its component.

Patch is attached.

Thanks,
Mikhail.

diff --git 
a/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java 
b/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java
--- a/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java
+++ b/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java
@@ -31,6 +31,8 @@
 import java.awt.KeyEventPostProcessor;
 import java.awt.Window;
 import java.awt.Toolkit;
+
+import sun.awt.AWTAccessor;
 import sun.awt.SunToolkit;
 
 import java.awt.event.ActionEvent;
@@ -133,10 +135,15 @@
                 // window. If this time appears to be greater than the 
altRelease
                 // event time the event is skipped to avoid unexpected menu
                 // activation. See 7121442.
+                // Also we must ensure that original source of key event 
belongs
+                // to the same window object as winAncestor. See 8001633.
                 boolean skip = false;
                 Toolkit tk = Toolkit.getDefaultToolkit();
                 if (tk instanceof SunToolkit) {
-                    skip = ev.getWhen() <= 
((SunToolkit)tk).getWindowDeactivationTime(winAncestor);
+                    Component originalSource = 
AWTAccessor.getKeyEventAccessor()
+                            .getOriginalSource(ev);
+                    skip = SunToolkit.getContainingWindow(originalSource) != 
winAncestor ||
+                            ev.getWhen() <= ((SunToolkit) 
tk).getWindowDeactivationTime(winAncestor);
                 }
 
                 if (menu != null && !skip) {
diff --git a/src/share/classes/java/awt/event/KeyEvent.java 
b/src/share/classes/java/awt/event/KeyEvent.java
--- a/src/share/classes/java/awt/event/KeyEvent.java
+++ b/src/share/classes/java/awt/event/KeyEvent.java
@@ -930,6 +930,10 @@
                                                long extendedKeyCode) {
                     ev.extendedKeyCode = extendedKeyCode;
                 }
+
+                public Component getOriginalSource( KeyEvent ev ) {
+                    return ev.originalSource;
+                }
             });
     }
 
@@ -939,6 +943,14 @@
      */
     private static native void initIDs();
 
+    /**
+     * The original event source.
+     *
+     * Event source can be changed during processing, but in some cases
+     * we need to be able to obtain original source.
+     */
+    private Component originalSource;
+
     private KeyEvent(Component source, int id, long when, int modifiers,
                     int keyCode, char keyChar, int keyLocation, boolean 
isProxyActive) {
         this(source, id, when, modifiers, keyCode, keyChar, keyLocation);
@@ -1023,6 +1035,7 @@
         } else if ((getModifiers() == 0) && (getModifiersEx() != 0)) {
             setOldModifiers();
         }
+        originalSource = source;
     }
 
     /**
diff --git a/src/share/classes/sun/awt/AWTAccessor.java 
b/src/share/classes/sun/awt/AWTAccessor.java
--- a/src/share/classes/sun/awt/AWTAccessor.java
+++ b/src/share/classes/sun/awt/AWTAccessor.java
@@ -629,6 +629,11 @@
          * Sets extendedKeyCode field for KeyEvent
          */
         void setExtendedKeyCode(KeyEvent ev, long extendedKeyCode);
+
+        /**
+         * Gets original source for KeyEvent
+         */
+        Component getOriginalSource(KeyEvent ev);
     }
 
     /**
diff --git 
a/test/javax/swing/plaf/windows/WindowsRootPaneUI/WrongAltProcessing/WrongAltProcessing.java
 
b/test/javax/swing/plaf/windows/WindowsRootPaneUI/WrongAltProcessing/WrongAltProcessing.java
new file mode 100644
--- /dev/null
+++ 
b/test/javax/swing/plaf/windows/WindowsRootPaneUI/WrongAltProcessing/WrongAltProcessing.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2012, 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 8001633
+   @summary Wrong alt processing during switching between windows
+   @author [email protected]
+   @run main WrongAltProcessing
+*/
+
+import sun.awt.SunToolkit;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+
+public class WrongAltProcessing {
+
+    private static Robot robot;
+    private static JFrame firstFrame;
+    private static JFrame secondFrame;
+    private static JTextField mainFrameTf1;
+    private static JTextField mainFrameTf2;
+    private static JTextField secondFrameTf;
+
+    public static void main(String[] args) throws AWTException {
+        try {
+            
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
+        } catch (Exception e) {
+            return;// miss unsupported platforms.
+        }
+        createWindows();
+        initRobot();
+        runScript();
+        verify();
+    }
+
+    private static void verify() {
+        Component c = DefaultKeyboardFocusManager
+                .getCurrentKeyboardFocusManager().getFocusOwner();
+        if (!(c == mainFrameTf2)) {
+            throw new RuntimeException("Wrong focus owner.");
+        }
+    }
+
+    public static void sync() {
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+        toolkit.realSync();
+    }
+
+    public static void initRobot() throws AWTException {
+        robot = new Robot();
+        robot.setAutoDelay(100);
+    }
+
+    private static void clickWindowsTitle(JFrame frame) {
+        Point point = frame.getLocationOnScreen();
+        robot.mouseMove(point.x + (frame.getWidth() / 2), point.y + 5);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+    }
+
+    public static void runScript() {
+        robot.delay(1000);
+        printABCD();
+        pressTab();
+        clickWindowsTitle(secondFrame);
+        robot.delay(500);
+        robot.keyPress(KeyEvent.VK_ALT);
+        robot.keyRelease(KeyEvent.VK_ALT);
+        clickWindowsTitle(firstFrame);
+        sync();
+    }
+
+    private static void pressTab() {
+        robot.keyPress(KeyEvent.VK_TAB);
+        robot.keyRelease(KeyEvent.VK_TAB);
+    }
+
+    private static void printABCD() {
+        robot.keyPress(KeyEvent.VK_A);
+        robot.keyRelease(KeyEvent.VK_A);
+        robot.keyPress(KeyEvent.VK_B);
+        robot.keyRelease(KeyEvent.VK_B);
+        robot.keyPress(KeyEvent.VK_C);
+        robot.keyRelease(KeyEvent.VK_C);
+        robot.keyPress(KeyEvent.VK_D);
+        robot.keyRelease(KeyEvent.VK_D);
+    }
+
+    public static void createWindows() {
+        firstFrame = new JFrame("Frame");
+        firstFrame.setLayout(new FlowLayout());
+
+        JMenuBar bar = new JMenuBar();
+        JMenu menu = new JMenu("File");
+        JMenuItem item = new JMenuItem("Save");
+
+        mainFrameTf1 = new JTextField(10);
+        mainFrameTf2 = new JTextField(10);
+
+        mainFrameTf1.addKeyListener(new KeyAdapter() {
+            public void keyPressed(KeyEvent EVT) {
+                if (EVT.getKeyChar() >= 'a' && EVT.getKeyChar() <= 'z') {
+                    try {
+                        // imitate some long processing
+                        Thread.sleep(2000);
+                    } catch (InterruptedException e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+            }
+        });
+
+        menu.add(item);
+        bar.add(menu);
+        firstFrame.setJMenuBar(bar);
+
+
+        firstFrame.add(mainFrameTf1);
+        firstFrame.add(mainFrameTf2);
+
+        firstFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+        firstFrame.pack();
+
+        secondFrame = new JFrame("Frame 2");
+        secondFrame.setLocation(0, 150);
+        secondFrameTf = new JTextField(20);
+        secondFrame.add(secondFrameTf);
+        secondFrame.pack();
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                secondFrame.setVisible(true);
+            }
+        });
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                firstFrame.setVisible(true);
+            }
+        });
+
+        mainFrameTf1.requestFocus();
+        sync();
+    }
+}

Reply via email to