6778087: getLocationOnScreen() always returns (0, 0) for mouse wheel events
authorserb
Mon, 17 Aug 2015 16:56:22 +0300
changeset 32295 5ba453554637
parent 32294 58789f875b54
child 32296 ee186af6c3ca
6778087: getLocationOnScreen() always returns (0, 0) for mouse wheel events Reviewed-by: alexsch, azvegint
jdk/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/PlatformEventNotifier.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformView.java
jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWarningWindow.java
jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp
jdk/test/java/awt/Mouse/MouseWheelAbsXY/MouseWheelAbsXY.java
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java	Thu Aug 06 19:52:02 2015 +0300
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java	Mon Aug 17 16:56:22 2015 +0300
@@ -746,7 +746,7 @@
      */
     @Override
     public void notifyMouseEvent(int id, long when, int button,
-                                 int x, int y, int screenX, int screenY,
+                                 int x, int y, int absX, int absY,
                                  int modifiers, int clickCount, boolean popupTrigger,
                                  byte[] bdata)
     {
@@ -763,7 +763,7 @@
                             this);
                     Component target = lastMouseEventPeer.getTarget();
                     postMouseExitedEvent(target, when, modifiers, lp,
-                            screenX, screenY, clickCount, popupTrigger, button);
+                            absX, absY, clickCount, popupTrigger, button);
                 }
 
                 // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched
@@ -781,7 +781,7 @@
                     Point lp = targetPeer.windowToLocal(x, y, this);
                     Component target = targetPeer.getTarget();
                     postMouseEnteredEvent(target, when, modifiers, lp,
-                            screenX, screenY, clickCount, popupTrigger, button);
+                            absX, absY, clickCount, popupTrigger, button);
                 }
                 lastCommonMouseEventPeer = targetPeer;
                 lastMouseEventPeer = targetPeer;
@@ -798,12 +798,12 @@
             // implemented in CPlatformEmbeddedFrame class
             if (topmostWindowPeer == this || topmostWindowPeer == null) {
                 generateMouseEnterExitEventsForComponents(when, button, x, y,
-                        screenX, screenY, modifiers, clickCount, popupTrigger,
+                        absX, absY, modifiers, clickCount, popupTrigger,
                         targetPeer);
             } else {
                 LWComponentPeer<?, ?> topmostTargetPeer = topmostWindowPeer.findPeerAt(r.x + x, r.y + y);
                 topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y,
-                        screenX, screenY, modifiers, clickCount, popupTrigger,
+                        absX, absY, modifiers, clickCount, popupTrigger,
                         topmostTargetPeer);
             }
 
@@ -874,7 +874,7 @@
             if (targetPeer.isEnabled()) {
                 MouseEvent event = new MouseEvent(targetPeer.getTarget(), id,
                                                   when, modifiers, lp.x, lp.y,
-                                                  screenX, screenY, clickCount,
+                                                  absX, absY, clickCount,
                                                   popupTrigger, button);
                 postEvent(event);
             }
@@ -885,7 +885,7 @@
                     postEvent(new MouseEvent(targetPeer.getTarget(),
                                              MouseEvent.MOUSE_CLICKED,
                                              when, modifiers,
-                                             lp.x, lp.y, screenX, screenY,
+                                             lp.x, lp.y, absX, absY,
                                              clickCount, popupTrigger, button));
                 }
                 mouseClickButtons &= ~eventButtonMask;
@@ -948,10 +948,10 @@
     }
 
     @Override
-    public void notifyMouseWheelEvent(long when, int x, int y, int modifiers,
-                                      int scrollType, int scrollAmount,
-                                      int wheelRotation, double preciseWheelRotation,
-                                      byte[] bdata)
+    public void notifyMouseWheelEvent(long when, int x, int y, int absX,
+                                      int absY, int modifiers, int scrollType,
+                                      int scrollAmount, int wheelRotation,
+                                      double preciseWheelRotation, byte[] bdata)
     {
         // TODO: could we just use the last mouse event target here?
         Rectangle r = getBounds();
@@ -963,12 +963,11 @@
 
         Point lp = targetPeer.windowToLocal(x, y, this);
         // TODO: fill "bdata" member of AWTEvent
-        // TODO: screenX/screenY
         postEvent(new MouseWheelEvent(targetPeer.getTarget(),
                                       MouseEvent.MOUSE_WHEEL,
                                       when, modifiers,
                                       lp.x, lp.y,
-                                      0, 0, /* screenX, Y */
+                                      absX, absY, /* absX, absY */
                                       0 /* clickCount */, false /* popupTrigger */,
                                       scrollType, scrollAmount,
                                       wheelRotation, preciseWheelRotation));
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/PlatformEventNotifier.java	Thu Aug 06 19:52:02 2015 +0300
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/PlatformEventNotifier.java	Mon Aug 17 16:56:22 2015 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -49,14 +49,14 @@
      * point of the client area is (insets.top, insets.left).
      */
     void notifyMouseEvent(int id, long when, int button,
-                          int x, int y, int screenX, int screenY,
+                          int x, int y, int absX, int absY,
                           int modifiers, int clickCount, boolean popupTrigger,
                           byte[] bdata);
 
-    void notifyMouseWheelEvent(long when, int x, int y, int modifiers,
-                               int scrollType, int scrollAmount,
-                               int wheelRotation, double preciseWheelRotation,
-                               byte[] bdata);
+    void notifyMouseWheelEvent(long when, int x, int y, final int absX,
+                               final int absY, int modifiers, int scrollType,
+                               int scrollAmount, int wheelRotation,
+                               double preciseWheelRotation, byte[] bdata);
     /*
      * Called by the delegate when a key is pressed.
      */
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java	Thu Aug 06 19:52:02 2015 +0300
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java	Mon Aug 17 16:56:22 2015 +0300
@@ -75,8 +75,8 @@
         int x = (int)pluginX;
         int y = (int)pluginY;
         Point locationOnScreen = getLocationOnScreen();
-        int screenX = locationOnScreen.x + x;
-        int screenY = locationOnScreen.y + y;
+        int absX = locationOnScreen.x + x;
+        int absY = locationOnScreen.y + y;
 
         if (eventType == CocoaConstants.NPCocoaEventMouseEntered) {
             CCursorManager.nativeSetAllowsCursorSetInBackground(true);
@@ -85,15 +85,19 @@
         }
 
         responder.handleMouseEvent(eventType, modifierFlags, buttonNumber,
-                                   clickCount, x, y, screenX, screenY);
+                                   clickCount, x, y, absX, absY);
     }
 
     public void handleScrollEvent(double pluginX, double pluginY, int modifierFlags,
                                   double deltaX, double deltaY, double deltaZ) {
         int x = (int)pluginX;
         int y = (int)pluginY;
+        Point locationOnScreen = getLocationOnScreen();
+        int absX = locationOnScreen.x + x;
+        int absY = locationOnScreen.y + y;
 
-        responder.handleScrollEvent(x, y, modifierFlags, deltaX, deltaY);
+        responder.handleScrollEvent(x, y, absX, absY, modifierFlags, deltaX,
+                                    deltaY);
     }
 
     public void handleKeyEvent(int eventType, int modifierFlags, String characters,
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java	Thu Aug 06 19:52:02 2015 +0300
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java	Mon Aug 17 16:56:22 2015 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -54,8 +54,7 @@
      * Handles mouse events.
      */
     void handleMouseEvent(int eventType, int modifierFlags, int buttonNumber,
-                          int clickCount, int x, int y, int absoluteX,
-                          int absoluteY) {
+                          int clickCount, int x, int y, int absX, int absY) {
         final SunToolkit tk = (SunToolkit)Toolkit.getDefaultToolkit();
         if ((buttonNumber > 2 && !tk.areExtraMouseButtonsEnabled())
                 || buttonNumber > tk.getNumberOfButtons() - 1) {
@@ -81,14 +80,15 @@
         boolean jpopupTrigger = NSEvent.isPopupTrigger(jmodifiers);
 
         eventNotifier.notifyMouseEvent(jeventType, System.currentTimeMillis(), jbuttonNumber,
-                x, y, absoluteX, absoluteY, jmodifiers, jclickCount,
+                x, y, absX, absY, jmodifiers, jclickCount,
                 jpopupTrigger, null);
     }
 
     /**
      * Handles scroll events.
      */
-    void handleScrollEvent(final int x, final int y, final int modifierFlags,
+    void handleScrollEvent(final int x, final int y, final int absX,
+                           final int absY, final int modifierFlags,
                            final double deltaX, final double deltaY) {
         final int buttonNumber = CocoaConstants.kCGMouseButtonCenter;
         int jmodifiers = NSEvent.nsToJavaMouseModifiers(buttonNumber,
@@ -97,18 +97,19 @@
 
         // Vertical scroll.
         if (!isShift && deltaY != 0.0) {
-            dispatchScrollEvent(x, y, jmodifiers, deltaY);
+            dispatchScrollEvent(x, y, absX, absY, jmodifiers, deltaY);
         }
         // Horizontal scroll or shirt+vertical scroll.
         final double delta = isShift && deltaY != 0.0 ? deltaY : deltaX;
         if (delta != 0.0) {
             jmodifiers |= InputEvent.SHIFT_DOWN_MASK;
-            dispatchScrollEvent(x, y, jmodifiers, delta);
+            dispatchScrollEvent(x, y, absX, absY, jmodifiers, delta);
         }
     }
 
-    private void dispatchScrollEvent(final int x, final int y,
-                                     final int modifiers, final double delta) {
+    private void dispatchScrollEvent(final int x, final int y, final int absX,
+                                     final int absY, final int modifiers,
+                                     final double delta) {
         final long when = System.currentTimeMillis();
         final int scrollType = MouseWheelEvent.WHEEL_UNIT_SCROLL;
         final int scrollAmount = 1;
@@ -118,8 +119,9 @@
             wheelRotation = signum;
         }
         // invert the wheelRotation for the peer
-        eventNotifier.notifyMouseWheelEvent(when, x, y, modifiers, scrollType,
-                scrollAmount, -wheelRotation, -delta, null);
+        eventNotifier.notifyMouseWheelEvent(when, x, y, absX, absY, modifiers,
+                                            scrollType, scrollAmount,
+                                            -wheelRotation, -delta, null);
     }
 
     /**
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformView.java	Thu Aug 06 19:52:02 2015 +0300
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformView.java	Mon Aug 17 16:56:22 2015 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -186,16 +186,19 @@
     }
 
 
-    private void deliverMouseEvent(NSEvent event) {
+    private void deliverMouseEvent(final NSEvent event) {
         int x = event.getX();
         int y = getBounds().height - event.getY();
+        int absX = event.getAbsX();
+        int absY = event.getAbsY();
 
         if (event.getType() == CocoaConstants.NSScrollWheel) {
-            responder.handleScrollEvent(x, y, event.getModifierFlags(),
+            responder.handleScrollEvent(x, y, absX, absY, event.getModifierFlags(),
                                         event.getScrollDeltaX(), event.getScrollDeltaY());
         } else {
             responder.handleMouseEvent(event.getType(), event.getModifierFlags(), event.getButtonNumber(),
-                                       event.getClickCount(), x, y, event.getAbsX(), event.getAbsY());
+                                       event.getClickCount(), x, y,
+                                       absX, absY);
         }
     }
 
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWarningWindow.java	Thu Aug 06 19:52:02 2015 +0300
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWarningWindow.java	Mon Aug 17 16:56:22 2015 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -173,7 +173,7 @@
 
     @Override
     public void notifyMouseEvent(int id, long when, int button, int x, int y,
-                                 int screenX, int screenY, int modifiers,
+                                 int absX, int absY, int modifiers,
                                  int clickCount, boolean popupTrigger,
                                  byte[] bdata) {
         LWWindowPeer peer = ownerPeer.get();
@@ -239,9 +239,10 @@
     }
 
     @Override
-    public void notifyMouseWheelEvent(long when, int x, int y, int modifiers,
-                                      int scrollType, int scrollAmount,
-                                      int wheelRotation, double preciseWheelRotation,
+    public void notifyMouseWheelEvent(long when, int x, int y, int absX,
+                                      int absY, int modifiers, int scrollType,
+                                      int scrollAmount, int wheelRotation,
+                                      double preciseWheelRotation,
                                       byte[] bdata) {
     }
 
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Thu Aug 06 19:52:02 2015 +0300
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Mon Aug 17 16:56:22 2015 +0300
@@ -4954,6 +4954,10 @@
         return;
     }
     jobject target = GetTarget(env);
+    DWORD curMousePos = ::GetMessagePos();
+    int xAbs = GET_X_LPARAM(curMousePos);
+    int yAbs = GET_Y_LPARAM(curMousePos);
+
     DTRACE_PRINTLN("creating MWE in JNI");
 
     jobject mouseWheelEvent = env->NewObject(mouseWheelEventCls,
@@ -4961,7 +4965,7 @@
                                              target,
                                              id, when, modifiers,
                                              x+insets.left, y+insets.top,
-                                             0, 0,
+                                             xAbs, yAbs,
                                              clickCount, popupTrigger,
                                              scrollType, scrollAmount,
                                              roundedWheelRotation, preciseWheelRotation);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Mouse/MouseWheelAbsXY/MouseWheelAbsXY.java	Mon Aug 17 16:56:22 2015 +0300
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+import java.awt.AWTException;
+import java.awt.Frame;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.Robot;
+import java.awt.Window;
+import java.awt.event.InputEvent;
+
+import static java.awt.GraphicsEnvironment.*;
+
+/**
+ * @test
+ * @bug 6778087
+ */
+public final class MouseWheelAbsXY {
+
+    private static boolean done;
+    private static int wheelX;
+    private static int wheelY;
+    private static int mouseX;
+    private static int mouseY;
+
+    public static void main(final String[] args) throws AWTException {
+        GraphicsEnvironment ge = getLocalGraphicsEnvironment();
+        GraphicsDevice[] sds = ge.getScreenDevices();
+        for (GraphicsDevice gd : sds) {
+            test(gd.getDefaultConfiguration());
+        }
+    }
+
+    private static void test(GraphicsConfiguration gc) throws AWTException {
+        final Window frame = new Frame(gc);
+        try {
+            frame.addMouseWheelListener(e -> {
+                wheelX = e.getXOnScreen();
+                wheelY = e.getYOnScreen();
+                done = true;
+            });
+            frame.setSize(300, 300);
+            frame.setVisible(true);
+
+            final Robot robot = new Robot();
+            robot.setAutoDelay(50);
+            robot.setAutoWaitForIdle(true);
+            mouseX = frame.getX() + frame.getWidth() / 2;
+            mouseY = frame.getY() + frame.getHeight() / 2;
+
+            robot.mouseMove(mouseX, mouseY);
+            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+            robot.mouseWheel(10);
+
+            validate();
+        } finally {
+            frame.dispose();
+        }
+    }
+
+    private static void validate() {
+        if (!done || wheelX != mouseX || wheelY != mouseY) {
+            System.err.println("Expected X: " + mouseX);
+            System.err.println("Expected Y: " + mouseY);
+            System.err.println("Actual X: " + wheelX);
+            System.err.println("Actual Y: " + wheelY);
+            throw new RuntimeException("Test failed");
+        }
+    }
+}