6778087: getLocationOnScreen() always returns (0, 0) for mouse wheel events

Reviewed-by: alexsch, azvegint
This commit is contained in:
Sergey Bylokhov 2015-08-17 16:56:22 +03:00
parent c595f6461c
commit 894f976f30
8 changed files with 149 additions and 44 deletions

View File

@ -746,7 +746,7 @@ public class LWWindowPeer
*/
@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 @@ public class LWWindowPeer
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 @@ public class LWWindowPeer
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 @@ public class LWWindowPeer
// 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 @@ public class LWWindowPeer
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 @@ public class LWWindowPeer
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 @@ public class LWWindowPeer
}
@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 @@ public class LWWindowPeer
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));

View File

@ -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 @@ public interface PlatformEventNotifier {
* 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.
*/

View File

@ -75,8 +75,8 @@ public class CEmbeddedFrame extends EmbeddedFrame {
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 @@ public class CEmbeddedFrame extends EmbeddedFrame {
}
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,

View File

@ -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 @@ final class CPlatformResponder {
* 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 @@ final class CPlatformResponder {
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 @@ final class CPlatformResponder {
// 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 @@ final class CPlatformResponder {
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);
}
/**

View File

@ -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 @@ public class CPlatformView extends CFRetainedResource {
}
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);
}
}

View File

@ -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 @@ public final class CWarningWindow extends CPlatformWindow
@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 @@ public final class CWarningWindow extends CPlatformWindow
}
@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) {
}

View File

@ -4954,6 +4954,10 @@ AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
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 @@ AwtComponent::SendMouseWheelEvent(jint id, jlong when, jint x, jint y,
target,
id, when, modifiers,
x+insets.left, y+insets.top,
0, 0,
xAbs, yAbs,
clickCount, popupTrigger,
scrollType, scrollAmount,
roundedWheelRotation, preciseWheelRotation);

View File

@ -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");
}
}
}