Make sure that the cursor position doesn't jump when switching grab mode

This commit is contained in:
Elias Naur 2006-11-24 14:53:01 +00:00
parent 57a8067a88
commit 63532ca647
5 changed files with 90 additions and 5 deletions

View File

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

View File

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

View File

@ -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() {

View File

@ -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) {

View File

@ -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();