6778087: getLocationOnScreen() always returns (0, 0) for mouse wheel events
Reviewed-by: alexsch, azvegint
--- 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");
+ }
+ }
+}