Use XInput2 RawMotion to generate MouseMotion events#19191
Use XInput2 RawMotion to generate MouseMotion events#19191KeyboardDanni wants to merge 0 commit into
Conversation
|
Uncovered an issue after some more testing,
|
|
With this latest commit, absolute motion is fixed, and mouse motion speed no longer feels too fast (the RawMotion event was getting received twice, due to a bug in X). Feel free to review. |
|
CC @RandomShaper @Hinsbart |
|
Formatting needs to be fixed (seee CI output) :) |
It's all cases where |
|
Ah yeah those are indeed weird. |
|
Could this PR be relabeled as a bug to be consistent with the issue it references? I am currently using Godot off of master with this fix applied because mouselook is too annoying to work with otherwise. |
|
I can't test this thoroughly at this time, but the idea seems good and the implementation looks sensible. |
|
Can you see if the ci error is fixable? |
|
I think the CI errors are false positives from a time where the master branch was not building. This PR needs to be squashed though to merge the fixups in the original commit and remove the "Merge branch" unnecessary commits (and fix current merge conflicts). |
|
I was under the impression that this PR was waiting on @RandomShaper to review it. But I can go ahead and squash the commits now. Those "Merge branch" commits were due to me resolving merge conflicts. This next "Merge branch" will be the third one. I was gonna wait until the alpha but given how frequently the merge conflicts are coming up, I'd rather have the PR merged now, if that's not an issue. When I squash, should the merges be squashed together with the rest? |
|
Yes, you should squash all 8 commits together, which will end up in this much more readable diff: https://github.com/godotengine/godot/pull/19191.diff |
|
Please ignore @neikeq, had a bad merge while trying to squash the commits initially. |
|
Your (master-rebased) PR doesn't work at all with absolute tracking mode devices, see The relative offset is now very different. It is more accelerated and in the confined mode the update continues on window edges. I do not know if the old behavior was expected ... |
|
What is the intended behavior here? Is the white dot meant to line up perfectly with the green dot? The mouse cursor and raw input events update at different rates so it's not likely to be possible. The reason it moves faster is because it does not account for mouse DPI. I could probably look into using the other values provided in the RawInput event, which do seem to compensate for it. Good catch on absolute mouse devices being broken. It looks like the axis values reported for absolute devices are in absolute coordinates, but are being interpreted as relative movement. I'll have to dig out my old Wacom tablet, it looks like. :) Edit: Relative motion going past the edges of the window/screen is intentional. Otherwise it'd break anything needing "infinite" mouse movement space. |
I meant the confined mode, check the current behaviour. |
|
Screencast to simplify. Notice how the cursor sits on godot's nose. godot HEAD 74359a1: Windows also have the first behavior. |
|
I think it's almost there. Issue with sliders (#19692) are fixed now (but not for touch): Pen and mouse seems fine but touch doesn't. See gifs below, the white dot always go back to the center. This means that we can't control 3d camera (freelook) or sliders with touch, for example. |
|
About resolution, here is a little comparison: On master (1093c0f): Mouse is two times slower, but is acceptable yet and with pen, is too small, I can barely move the slider. |
|
Is the touch device detected as an absolute or relative device? What does "xinput test-xi2" give for it? I unfortunately do not know how I would get a touch device working on my setup. I don't have any touch screens (outside of Android devices). I have an Apple trackpad and a PS4 controller, both of which should be multi-touch capable yet aren't picked up as such. I'll up the pen sensitivity. For mouse, what Godot really needs is an editor option to control the capture speed, because this is going to be slightly different on every configuration. |
absolute
The stranger part about this is that I only have small resolution when moving sliders, for freelook or using the test case with colored dots I don't get any issue with resolution. Maybe it's a bug with sliders 🤔 |
|
Slider sensitivity is the least of my concerns right now. What I really want to do is fix the touch issues. So far nobody has been able to help me get multitouch set up, but you appear to have a working configuration, so you'll need to work with me to get this resolved. I don't know what kind of hardware setup you have - specifically, what is the touch device? And I would still like to see the output from "xinput test-xi2". |
|
I'm using touch of my Wacom Intuos Pro M. Full log for pen: https://gist.github.com/guilhermefelipecgs/5d3ab6344e9d5775572fe4f0d34911ca and here is the log when I "change devices": https://gist.github.com/guilhermefelipecgs/842a25d3f26632359434c5caf5496ef2 Update:Full log for touch after changing to relative: https://gist.github.com/guilhermefelipecgs/b56d8ccc97120d54ad233787d380666f |
|
When using touch of wacom, the device should not be treated as absolute anymore. I think this should works. Update:When reading the "change devices" log, it seems that the wacom reports finger touch as absolute mode, but it doesn't (should not be, because it works as relative for me). Update 2:
|
|
@cosmicchipsocket I don't have any problems anymore, my wacom was not reporting correct values for linux, maybe it's a driver bug. Mouse, Pen and Touch are working good, I don't have any other complain about this PR except for the sensitivity with slider that maybe should not be treated here. Thanks. |
|
Almost forget, I think my wacom support multi touch but I don't know how to test it. I'll try to discover. |
|
Ok, I think my wacom is not considered has touch device. |
|
@guilhermefelipecgs Thanks for the update! |
|
@cosmicchipsocket IMO we can safely have a strong requirement on XInput 2 given its age and widespread availability. That should simplify things a bit and avoid keeping code that we'll never use in the end. CC @hpvb |
GLFW did that more than a year ago |
|
FWIW, this pull request seems to really fix godotengine/godot-docs#1774 for me on linux. if i understand this MOUSE_MODE_CAPTURED correctly, the current (godot git master couple hours ago) method to get around the problem that xorg (xcb?) wont give us any mouse movement when pointer is at window edge, is to warp the mouse pointer to the center of the window, on every mouse move? and this pull request - i assume (did not read, just merged and works. and gotta get sleep) - allows us to get mouse movement constantly? that sounds like a perfect solution for a 3d fps camera movement with MOUSE_MODE_CAPTURED!
|
Bump @cosmicchipsocket, could you do those changes? (make XInput 2.0 strong requirement, only keep the 2.2 checks for the touch feature). |
|
Dissolved the XI_ENABLED ifdef and removed the xinput option from detect.py (reverting it to its original state). Also went ahead and fixed an issue where the faux global mouse position was still stairsteppy in captured mode with a relative device. |
|
In the Free-Cam (F) view, the relative device is about twice? as sensitive as before (independent to the mouse speed OS settings). Otherwise everything lgtm. |
|
Now the engine and buildsystem will fail out if XInput 2 is missing. Feeling like this is more or less done now. |
|
Sorry about the auto-close, I tried to force push a rebased commit but I pushed the wrong branch, which closed the PR as it was the same as current I've actually merged this PR manually as cf124b1. |














Fixes issue #19031.
A few things worth mentioning:
Commit message:
The current system for capturing the mouse and generating motion events on X11
has issues with inaccurate and lopsided input. This is because both
XQueryPointer and XWarpPointer work in terms of integer coordinates when the
underlying X11 input driver may be tracking the mouse using subpixel
coordinates. When warping the pointer, the fractional part of the pointer
position is discarded.
To work around this issue, the fix uses raw motion events from XInput 2. These
events report relative motion and are not affected by pointer warping.
Additionally, this means Godot is able to detect motion at a higher resolution
under X11. Because this is raw mouse input, it is not affected by the user's
pointer speed and acceleration settings. This is the same system as SDL2 uses
for its relative motion.
This change introduces a new build option, "xinput2", which defines XI_ENABLED.
As "touch" relies on XInput, it now implies "xinput2". Multitouch input on X
requires XInput 2.2. Raw motion events require XInput 2.0. If XI_ENABLED is not
defined, the old mouse motion behavior is used. Older systems that require
"xinput2" disabled are likely to be using the "xf86-input-evdev" driver which
is not affected by the bug this commit addresses.