Make sure that the cursor position doesn't jump when switching grab mode
This commit is contained in:
parent
57a8067a88
commit
63532ca647
|
@ -570,6 +570,10 @@ public class Mouse {
|
||||||
isGrabbed = grab;
|
isGrabbed = grab;
|
||||||
if (isCreated()) {
|
if (isCreated()) {
|
||||||
implementation.grabMouse(isGrabbed);
|
implementation.grabMouse(isGrabbed);
|
||||||
|
// Get latest values from native side
|
||||||
|
poll();
|
||||||
|
event_x = x;
|
||||||
|
event_y = y;
|
||||||
resetMouse();
|
resetMouse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,9 @@ package org.lwjgl.opengl;
|
||||||
|
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.GraphicsDevice;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.IllegalComponentStateException;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Robot;
|
import java.awt.Robot;
|
||||||
|
@ -106,12 +108,75 @@ final class AWTUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int transformY(Component component, int y) {
|
||||||
|
return component.getHeight() - 1 - y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use reflection to access the JDK 1.5 pointer location, if possible and
|
||||||
|
* only if the given component is on the same screen as the cursor. Return
|
||||||
|
* null otherwise.
|
||||||
|
*/
|
||||||
|
private static Point getPointerLocation(final Component component) {
|
||||||
|
try {
|
||||||
|
final Class MouseInfo_class = Class.forName("java.awt.MouseInfo");
|
||||||
|
final Method getPointerInfo_method = MouseInfo_class.getMethod("getPointerInfo", null);
|
||||||
|
final Class PointerInfo_class = Class.forName("java.awt.PointerInfo");
|
||||||
|
final Method getDevice_method = PointerInfo_class.getMethod("getDevice", null);
|
||||||
|
final Method getLocation_method = PointerInfo_class.getMethod("getLocation", null);
|
||||||
|
return (Point)AccessController.doPrivileged(new PrivilegedExceptionAction() {
|
||||||
|
public final Object run() throws Exception {
|
||||||
|
Object pointer_info = getPointerInfo_method.invoke(null, null);
|
||||||
|
GraphicsDevice device = (GraphicsDevice)getDevice_method.invoke(pointer_info, null);
|
||||||
|
if (device == component.getGraphicsConfiguration().getDevice()) {
|
||||||
|
return (Point)getLocation_method.invoke(pointer_info, null);
|
||||||
|
} else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (PrivilegedActionException e) {
|
||||||
|
LWJGLUtil.log("Failed to query pointer location: " + e.getCause());
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
LWJGLUtil.log("Failed to query pointer location: " + e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
LWJGLUtil.log("Failed to query pointer location: " + e);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
LWJGLUtil.log("Failed to query pointer location: " + e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the 1.5 API to get the cursor position relative to the component. Return null
|
||||||
|
* if it fails (JDK <= 1.4).
|
||||||
|
*/
|
||||||
|
public static Point getCursorPosition(Component component) {
|
||||||
|
try {
|
||||||
|
Point pointer_location = getPointerLocation(component);
|
||||||
|
if (pointer_location != null) {
|
||||||
|
Point location = component.getLocationOnScreen();
|
||||||
|
pointer_location.translate(-location.x, -location.y);
|
||||||
|
pointer_location.move(pointer_location.x, transformY(component, pointer_location.y));
|
||||||
|
return pointer_location;
|
||||||
|
}
|
||||||
|
} catch (IllegalComponentStateException e) {
|
||||||
|
LWJGLUtil.log("Failed to set cursor position: " + e);
|
||||||
|
} catch (NoClassDefFoundError e) { // Not JDK 1.5
|
||||||
|
LWJGLUtil.log("Failed to query cursor position: " + e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static void setCursorPosition(Component component, Robot robot, int x, int y) {
|
public static void setCursorPosition(Component component, Robot robot, int x, int y) {
|
||||||
if (robot != null) {
|
if (robot != null) {
|
||||||
|
try {
|
||||||
Point location = component.getLocationOnScreen();
|
Point location = component.getLocationOnScreen();
|
||||||
int transformed_x = location.x + x;
|
int transformed_x = location.x + x;
|
||||||
int transformed_y = location.y + component.getHeight() - 1 - y;
|
int transformed_y = location.y + transformY(component, y);
|
||||||
robot.mouseMove(transformed_x, transformed_y);
|
robot.mouseMove(transformed_x, transformed_y);
|
||||||
|
} catch (IllegalComponentStateException e) {
|
||||||
|
LWJGLUtil.log("Failed to set cursor position: " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,7 +173,15 @@ final class LinuxMouse {
|
||||||
public void changeGrabbed(boolean grab, boolean warp_pointer) {
|
public void changeGrabbed(boolean grab, boolean warp_pointer) {
|
||||||
reset();
|
reset();
|
||||||
long root_window = nQueryPointer(display, window, query_pointer_buffer);
|
long root_window = nQueryPointer(display, window, query_pointer_buffer);
|
||||||
doHandlePointerMotion(grab, warp_pointer, root_window, query_pointer_buffer.get(0), query_pointer_buffer.get(1), query_pointer_buffer.get(2), query_pointer_buffer.get(3), last_event_nanos);
|
|
||||||
|
int root_x = query_pointer_buffer.get(0);
|
||||||
|
int root_y = query_pointer_buffer.get(1);
|
||||||
|
int win_x = query_pointer_buffer.get(2);
|
||||||
|
int win_y = query_pointer_buffer.get(3);
|
||||||
|
// Pretend that the cursor never moved
|
||||||
|
last_x = win_x;
|
||||||
|
last_y = transformY(win_y);
|
||||||
|
doHandlePointerMotion(grab, warp_pointer, root_window, root_x, root_y, win_x, win_y, last_event_nanos);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getButtonCount() {
|
public int getButtonCount() {
|
||||||
|
|
|
@ -42,6 +42,7 @@ import java.awt.event.MouseMotionListener;
|
||||||
import java.awt.event.MouseWheelEvent;
|
import java.awt.event.MouseWheelEvent;
|
||||||
import java.awt.event.MouseWheelListener;
|
import java.awt.event.MouseWheelListener;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.Point;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
|
|
||||||
|
@ -112,6 +113,11 @@ class MouseEventQueue extends EventQueue implements MouseListener, MouseMotionLi
|
||||||
protected void resetCursorToCenter() {
|
protected void resetCursorToCenter() {
|
||||||
clearEvents();
|
clearEvents();
|
||||||
accum_dx = accum_dy = 0;
|
accum_dx = accum_dy = 0;
|
||||||
|
Point cursor_location = AWTUtil.getCursorPosition(component);
|
||||||
|
if (cursor_location != null) {
|
||||||
|
last_x = cursor_location.x;
|
||||||
|
last_y = cursor_location.y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putMouseEvent(byte button, byte state, int dz, long nanos) {
|
private void putMouseEvent(byte button, byte state, int dz, long nanos) {
|
||||||
|
|
|
@ -242,6 +242,8 @@ public class MouseTest {
|
||||||
if(Mouse.getEventButton() != -1 && Mouse.getEventButtonState()) {
|
if(Mouse.getEventButton() != -1 && Mouse.getEventButtonState()) {
|
||||||
lastButton = Mouse.getEventButton();
|
lastButton = Mouse.getEventButton();
|
||||||
}
|
}
|
||||||
|
if (Mouse.getEventDX() != 0 || Mouse.getEventDY() != 0)
|
||||||
|
System.out.println("Mouse.getEventDX() = " + Mouse.getEventDX() + " | Mouse.getEventDY() = " + Mouse.getEventDY());
|
||||||
}
|
}
|
||||||
|
|
||||||
updateState();
|
updateState();
|
||||||
|
|
Loading…
Reference in New Issue