How to avoid mouse cursor jumping while using xinput Coordinate Transformation Matrix when application releases mouse

javakdeminecraftmousexinput

I've got some high sensitivity mice that I need to lower the sensitivity on. The general solution to this seems to be to set the Coordinate Transformation Matrix to something acceptable. So I use the following values:

xinput --set-prop 19 'Coordinate Transformation Matrix' 0.25 0 0  0 0.25 0  0 0 1

This works fine, except, that I finally realized it was causing me issues while playing minecraft. 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.

I need advice as to how to avoid this cursor movement. It's quite maddening. I also don't think this is strictly a minecraft issue, and I suspect it happens with other java applications that take and release the mouse cursor.

Further information, my machine is running Kubuntu 18.04 and openJDK 10.0.2.

Edit: Adding more info. I'm starting to notice this behavior in other places during my normal workflow. It's not clear when, but maybe has to do with how KDE is dealing with the mouse events and window focus. I use follow mouse – mouse precedence.

Best Answer

My "solution" was to pick a transformation matrix that keeps the cursor in place when it is centered.

The matrix you want to use is:

3 by 3 matrix s 0 (1-s)x 0 s (1-s)y 0 0 1

Where s is the scaling factor you want for your mouse, e.g. 0.5 for half speed. And x and y are the coordinates for the center of your screen.

An easy way to get the x,y value is with xdotool getmouselocation before a jump.

Example

I wanted my sensitivity s = 0.4

After opening my inventory in minecraft, xdotool getmouseloation reports my x = 960 and y = 1729. Calculating my offsets (1-s)*x = 0.6*960 = 576 and (1-s)*y = 0.6*1729 = 1037.4

I then changed the Coordinate transformation matrix accordingly

xinput set-prop 8 'Coordinate Transformation Matrix' 0.4 0 576 0 0.4 1037.4 0 0 1

(My mouse is device 8 will likely be different for you.)

Flaws

This only fixes the issue for a specific coordinate. For something like Minecraft where you are generally keeping the window in the same position this fix is good enough and your mouse will no longer jump at all when going into your inventory.

In other use cases you'll still experience jumps, but the jumps will be smaller when your mouse is close to your chosen x,y.

Math Details

For extra details of the mathematics see https://math.stackexchange.com/questions/2954781/calculating-the-translation-of-an-affine-matrix-so-that-it-centres-during-scalin

Related Question