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;
|
||||
if (isCreated()) {
|
||||
implementation.grabMouse(isGrabbed);
|
||||
// Get latest values from native side
|
||||
poll();
|
||||
event_x = x;
|
||||
event_y = y;
|
||||
resetMouse();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,9 @@ package org.lwjgl.opengl;
|
|||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Component;
|
||||
import java.awt.GraphicsDevice;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.IllegalComponentStateException;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
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) {
|
||||
if (robot != null) {
|
||||
Point location = component.getLocationOnScreen();
|
||||
int transformed_x = location.x + x;
|
||||
int transformed_y = location.y + component.getHeight() - 1 - y;
|
||||
robot.mouseMove(transformed_x, transformed_y);
|
||||
try {
|
||||
Point location = component.getLocationOnScreen();
|
||||
int transformed_x = location.x + x;
|
||||
int transformed_y = location.y + transformY(component, 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) {
|
||||
reset();
|
||||
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() {
|
||||
|
|
|
@ -42,6 +42,7 @@ import java.awt.event.MouseMotionListener;
|
|||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.event.MouseWheelListener;
|
||||
import java.awt.Component;
|
||||
import java.awt.Point;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
|
@ -112,6 +113,11 @@ class MouseEventQueue extends EventQueue implements MouseListener, MouseMotionLi
|
|||
protected void resetCursorToCenter() {
|
||||
clearEvents();
|
||||
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) {
|
||||
|
|
|
@ -242,6 +242,8 @@ public class MouseTest {
|
|||
if(Mouse.getEventButton() != -1 && Mouse.getEventButtonState()) {
|
||||
lastButton = Mouse.getEventButton();
|
||||
}
|
||||
if (Mouse.getEventDX() != 0 || Mouse.getEventDY() != 0)
|
||||
System.out.println("Mouse.getEventDX() = " + Mouse.getEventDX() + " | Mouse.getEventDY() = " + Mouse.getEventDY());
|
||||
}
|
||||
|
||||
updateState();
|
||||
|
|
Loading…
Reference in New Issue