Mouse jumps apply CoordinateTransformationMatrix to the aboslute cursor position
Summary
If a non-default Coordinate Transformation Matrix is specified for a mouse, then when the mouse is moved to an absolute position, it unexpectedly jumps again upon the next mouse input event. Xorg seems to be interpreting this cursor jump like a touchscreen event, applying the CoordinateTransformationMatrix to the absolute mouse coordinates.
Steps to reproduce
Using xdotool
:
- Set a non-default CoordinateTransformationMatrix for the mouse device; e.g.
1 0 0 0 1 0 0 0 2
- Run
xdotool mousemove -- 100 100
- Note that when the mouse is first moved, the cursor immediately jumps to a location near the upper-left corner of the screen
Using i3wm (resizing windows):
- Set a non-default CoordinateTransformationMatrix for the mouse device; e.g.
1 0 0 0 1 0 0 0 2
- Open two windows tiled side-by-side (Mod+Enter opens a terminal by default, where "Mod" is either Super or Alt)
- Hold the Mod key (Super or Alt) while right-click-dragging between the two to resize them
- i3wm teleports the mouse to be directly between the two windows, as expected
- Note that when the mouse button is released or the mouse is first moved while dragging, the cursor immediately jumps to a location near the upper-left corner of the screen
Using i3wm (multi-monitor):
- Set a non-default CoordinateTransformationMatrix for the mouse device; e.g.
1 0 0 0 1 0 0 0 2
- Ensure that
mouse_warping output
is present in the i3wm configuration (this is the default behavior) - Use the keyboard to shift window focus between monitors; the mouse should follow
- Move the mouse slightly
- Note that when the mouse is first moved, the cursor immediately jumps to a location near the upper-left corner of the screen
Using Minecraft:
- Set a non-default CoordinateTransformationMatrix for the mouse device; e.g.
1 0 0 0 1 0 0 0 2
- Open Minecraft >=1.13 (tested using snapshot 19w04b; untested in Minecraft <1.13 before LWJGL3)
- Enter a world
- Open the pause menu or inventory screen
- Move the mouse slightly
- Note that when the mouse is first moved, the cursor immediately jumps to a location near the upper-left corner of the screen
Using a custom-made LWJGL demo:
- Set a non-default CoordinateTransformationMatrix for the mouse device; e.g.
1 0 0 0 1 0 0 0 2
- Ensure that Maven is installed along with some version of the JDK
- Clone, compile, and run
https://github.com/HactarCE/lwjgl3-demos
:
git clone https://github.com/HactarCE/lwjgl3-demos \
&& cd lwjgl3-demos \
&& mvn package \
&& java -jar target/lwjgl3-demos.jar \
- Press
z
to "disable" the cursor, then pressx
orc
to undisable it - Move the mouse slightly
- Note that when the mouse is first moved, the cursor immediately jumps to a location near the upper-left corner of the screen
Further information
I originally submitted this bug here on Libinput's issue tracker (and then mistakenly submitted it here to xinput's issue tracker), but was deferred here as this was deemed to most likely be a bug with Xorg.
Another user has posted about this issue on the Unix & Linux Stack Exchange, describing similar behavior:
What happens, is that when I hit any key that gives me back my cursor, as soon as I move my mouse, the cursor jumps to the top left quadrant of my screen. The exact position is proportional to the scaling number I use, so .25 moves the cursor closer to the corner than .45. Moreover, if I use a value greater than 1, the cursor moves to a different quadrant of my monitor. And, of course, values of 1 leave the cursor in the center of the screen as expected. This just happens on the first mouse input, and the mouse behaves normally after that.
This is exactly what I am seeing as well. Note that the issue only seems to occur in the demo when the pointer is "disabled" with z
(hidden + captured) and then undisabled with x
or c
; pressing x
to "hide" the cursor and c
to unhide it does not cause the problem.
This bug was also briefly noted in this StackExchange answer (see UPD at the bottom) as undesirable behavior, but is implicitly assumed to be an issue with Wine.
Other log output:
I am using libinput; here is some debug info regarding that:
-
libinput record
output (using Minecraft): libinput-mouse-capture-and-release-record.txt -
libinput debug-events --verbose
output (using LWJGL demo): libinput-mouse-capture-and-release-debug-events.txt
I have added some comments beginning with ####
to the above files to identify where I "disabled"/undisabled the cursor. (Undisabling it caused a cursor jump.)