[BUG] Mouse.setGrabbed(true) briefly ignores button release event

Started by PlanckWalk, October 15, 2011, 21:55:55

Previous topic - Next topic

PlanckWalk

I use mouse-drag to rotate the camera in my application, and noticed that sometimes the mouse would get "stuck down" if I clicked instead of dragging.

I tracked this down to the mouse event code losing the "mouse button release" event when calling Mouse.setGrabbed(true), and so never calling Mouse.setGrabbed(false).

This occurs on linux 64-bit system, across both Java 6 32-bit and Java 7 64-bit, and both LWJGL 2.7.1 and 2.8.0.  A short test case follows:
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;

public class TestLWJGL {
	public static void main(String[] args) throws Exception {
		Display.create();
		while (!Display.isCloseRequested()) {
			Display.update();
			while (Mouse.next()) {
				if (Mouse.getEventButton() == 0) {
					Mouse.setGrabbed(Mouse.getEventButtonState());
				}
			}
		}
	}
}

When run, it should hide the mouse pointer (grab) when the mouse button is pressed, and show the pointer again when it is released (ungrab).  It does this with sufficient interval between press and release, but fails to do so if clicked (press and release immediately).

I have worked around this by not grabbing the mouse.

kappa

A quick look at the LWJGL code shows that the mouse event queue is cleared when Mouse.setGrabbed(boolean) is called, which would mean that if the release mouse button event is in the current mouse event queue it'll be cleared and not register. It also seems from the code (not tested) that the same behaviour should happen on Windows too.

princec


kappa

Quote from: princec on October 20, 2011, 12:07:25
Any idea why the event queue is cleared?

Its not obvious from looking at the Windows and Linux implementations, however looking into the Mac version (which indecently doesn't clear the event queue on mouse grab) there is a line which gives a clue as to why clearing the event queue might have been added.

// If we're going to warp the cursor position, we'll skip the next event to avoid bogus delta values
skip_event = isGrabbed();