libsdl-org / SDL

Simple Directmedia Layer
https://libsdl.org
zlib License
9.44k stars 1.76k forks source link

SDL_SetRelativeMouseMode causes xrel/yrel in SDL_MOUSEMOTION to be large absolute values #1836

Open SDLBugzilla opened 3 years ago

SDLBugzilla commented 3 years ago

This bug report was migrated from our old Bugzilla tracker.

Reported in version: 2.0.3 Reported for operating system, platform: Linux, x86_64

Comments on the original bug report:

On 2015-04-21 23:59:20 +0000, Wouter van Oortmerssen wrote:

values in xrel/yrel range from 0..64k, and correspond to the extends of the linux desktop (not my SDL window), or 0 when no movement along the axis.

On Win/Mac I get correct relative values, as does Linux when SDL_SetRelativeMouseMode is not used.

On 2016-01-19 22:43:01 +0000, Anthony Birkett wrote:

Same issue on Debian.

In testing, this appears to be a problem when running on Wayland, or in a Virtual Machine.

Debian Jessie amd64 VMWare 12 X11 + Gnome SDL_SetMouseRelativeMode(SDL_TRUE) - bad xrel and yrel values.

Debian Sid amd64 Thinkpad W530 bare metal X11 + Gnome SDL_SetMouseRelativeMode(SDL_TRUE) - working fine.

Debian Sid amd64 Thinkpad W530 bare metal Wayland + Gnome SDL_SetMouseRelativeMode(SDL_TRUE) - bad xrel and yrel values.

Setting SDL_SetMouseRelativeMode(SDL_FALSE) seems to help, but defeats the point of capturing mouse movement.

On 2016-01-19 23:00:15 +0000, Anthony Birkett wrote:

To add,

SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1", SDL_HINT_OVERRIDE);

This does help, but doesn't seem to warp the mouse back to center.

On 2016-01-20 20:26:03 +0000, Philipp Wiesemann wrote:

There is currently no relative mouse mode and no warping implemented in SDL for Wayland.

SDL_SetRelativeMouseMode() should return -1 if there is no support for relative mouse mode.

The (later) bug # 3226 describes similar problems on Android where it is also not implemented.

On 2016-01-23 18:52:10 +0000, Wouter van Oortmerssen wrote:

Yes, for me this also happens in a VirtualBox VM (one that has been set up with 2d & 3d hardware accelleration, latest version, latest guest drivers).

Thing is, if SDL_SetMouseRelativeMode failing with -1 is the cause of the problem, why does it still affect the xrel/yrel values? These values seem to work fine if SDL_SetMouseRelativeMode is never called.

I'm not familiar with what kind of support SDL_SetMouseRelativeMode needs from the system, but wouldn't it be more useful if instead of failing it emulated relative mouse mode values to the best of its abilities (by supplying the delta between the last two mouse positions) rather than bogus values?

On 2018-09-29 21:32:52 +0000, wrote:

From https://bugzilla.libsdl.org/show_bug.cgi?id=2150 - this occurs on Ubuntu Linux 18.04.1 in a VMware Fusion virtual machine, the above workaround posted works however (also thanks to https://stackoverflow.com/questions/25576438/sdl-getrelativemousestate-strange-behaviour).

Example test program, uncomment hint to demonstrate the issue:

// cc sdlmotion.c -lSDL2
#include <SDL2/SDL.h>

int main() {
        SDL_Window *window = SDL_CreateWindow("Demo Game", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_OPENGL);
        SDL_Event event;

// https://stackoverflow.com/questions/25576438/sdl-getrelativemousestate-strange-behaviour
SDL_SetHintWithPriority(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1", SDL_HINT_OVERRIDE);

        printf("SDL_SetRelativeMouseMode = %d\n", SDL_SetRelativeMouseMode(SDL_TRUE));

        do {
                while(SDL_PollEvent(&event)) {
                        switch(event.type) {
                        case SDL_QUIT: exit(0);
                        case SDL_MOUSEMOTION:
                                printf("x=%d, y=%d, xrel=%d, yrel=%d\n", event.motion.x, event.motion.y, event.motion.xrel, event.motion.yrel);
                        }
                }
        } while(1);
}

On 2019-09-19 11:43:49 +0000, Stijn Volckaert wrote:

I am also seeing this issue with SDL 2.0.10. I'm testing on Ubuntu 18.04 in a VMWware Workstation 15 Player VM. The above workaround stops the extreme mouse warping but it still doesn't quite fix everything as the mouse input now lags a LOT. I did not see this issue on Mac.

On 2019-09-19 12:26:47 +0000, Stijn Volckaert wrote:

Additional information:

  • This also happens on Ubuntu 14.04.6 LTS 32-bit (in a VMWare Workstation 15 Player VM)
  • Even with the workaround, my xrel/yrel values make no sense. They're just absolute positions relative to the center of the window
  • Once I reach the edge of the window, my xrel/yrel values become 0

On 2019-09-19 20:10:33 +0000, Stijn Volckaert wrote:

What Wouter said seems to apply to VMware in its default configuration. Setting vmmouse.present to false in my vm configuration solved this problem. I did not need the warp hint after doing this.

mika314 commented 2 years ago

Any updates or workarounds on this bug?

icculus commented 2 years ago

Any updates or workarounds on this bug?

Does setting vmmouse.present to false not work anymore? This appears to be a quirk of vmware...?

mika314 commented 2 years ago

Any updates or workarounds on this bug?

Does setting vmmouse.present to false not work anymore? This appears to be a quirk of vmware...?

I have the issue with the pen tablet (not in vmware) the values of xrel and yrel are crazy high. I made some hacky workaround for it last night.

If anyone is interested, TLDR; if values are crazy high switch back to non-relative mode.

modified   Engine/Source/ThirdParty/SDL2/SDL-gui-backend/src/video/x11/SDL_x11xinput2.c
@@ -192,6 +192,11 @@ X11_HandleXinput2Event(SDL_VideoData *videodata,XGenericEventCookie *cookie)
                 return 0;  /* duplicate event, drop it. */
             }

+            if (relative_coords[0] > 100. || relative_coords[1] > 100.) {
+              SDL_SetRelativeMouseMode(SDL_FALSE);
+              return 0;
+            }
+
             SDL_SendMouseMotion(mouse->focus,mouse->mouseID,1,(int)relative_coords[0],(int)relative_coords[1]);
             prev_rel_coords[0] = relative_coords[0];
slouken commented 2 years ago

Is this a bug in XInput?

icculus commented 2 years ago

Is this a bug in XInput?

I haven't looked at this yet, but I'd bet anything that we are screwing up with devices that report absolute coordinates instead of relative.

(and this may or may not be a separate issue from the vmware thing.)

slouken commented 2 years ago

Yeah, it makes sense that we're not handling absolute coordinates correctly. I moved this to 2.0.24 for investigation.

icculus commented 2 years ago

Ok, looked into this, and we don't check the XIValuatorClass of devices at all, which means we accept absolute coordinates as relative values.

Scratching this together shortly, which I think will fix this issue.

icculus commented 2 years ago

I've pushed an attempt at this, but I can't find my tablet, which might have been thrown out a long time ago, so someone is going to have to tell me if it works.

It definitely still works in the not-absolute-coordinate case, but that's all I can promise here at the moment.

icculus commented 2 years ago

Anyone with a tablet have a chance to see if the latest in revision control fixes this issue? @mika314?

mika314 commented 2 years ago

I am too lazy, I have a workaround. It takes forever to rebuild Unreal Engine.

icculus commented 2 years ago

I'm going to kick this out of the milestone and try to find a device for 2.26; in the worst case, we're not any worse off than we were, so I think we're good for 2.24.

BrandonSchaefer commented 2 years ago

I was tracking this down a bit as Unreal Editor is hitting this in TigerVNC, annnd testing this new patch and still running into the same issue. Digging a little more found a few things:

Using xinput test-xi2 --root on my normal X11 server my general events when doing relative work look like:

EVENT type 6 (Motion)
    device: 8 (8)
    detail: 0
    flags: 
    root: 663.55/468.61
    event: 663.55/468.61
    buttons:
    modifiers: locked 0 latched 0 base 0x4 effective: 0x4
    group: locked 0 latched 0 base 0 effective: 0
    valuators:
        0: 673.55
        1: 470.61
    windows: root 0x1e8 event 0x1e8 child 0x2c0000a
EVENT type 17 (RawMotion)
    device: 2 (8)
    detail: 0
    flags: 
    valuators:
          0: 6.00 (3.00)
          1: 2.00 (1.00)

While on TigerVNC:

EVENT type 6 (Motion)
    device: 6 (6)
    detail: 0
    flags: 
    root: 346.00/727.00
    event: 346.00/727.00
    buttons:
    modifiers: locked 0 latched 0 base 0x4 effective: 0x4
    group: locked 0 latched 0 base 0 effective: 0
    valuators:
        0: 328.00
        1: 715.00
    windows: root 0x3b3 event 0x3b3 child 0x240328e
EVENT type 17 (RawMotion)
    device: 2 (6)
    detail: 0
    flags: 
    valuators:
          0: 326.00 (326.00)
          1: 709.00 (709.00)

Which you can see for the RawMotion event... is using Absolute, which can be fine BUT further compounding the issue is:

 for (i = 0; i < 2; i++) {
    if (devinfo->relative[i]) {
        processed_coords[i] = coords[i];
    } else {
        processed_coords[i] = devinfo->prev_coords[i] - coords[i];    /* convert absolute to relative */
    }
}
// ...
 devinfo->relative[axis] = (v->mode == XIModeRelative) ? SDL_TRUE : SDL_FALSE;

Is True... so the valuator thinks its relative, while event coords are not. I can see the issue using xinput test-xi2, which is not using SDL2.

Im not 100% if all the causes are caused by the same issues here... but seems more related to the x11 server directly (Ive not tried any wayland servers out yet) vs SDL at this point.

slouken commented 2 years ago

So TigerVNC is lying and saying it's relative motion even though they're absolute coordinates?

BrandonSchaefer commented 2 years ago

Yeah looking at bug reports over there, some talk on this (granted this vnc bug is mouse warping, and VNC not being able to hold onto the mouse vs a direct client...) https://github.com/TigerVNC/tigervnc/issues/619

Ive not looked at their source, though the original bug report here was VMWare stuff not TigerVNC, but we have had issues on Unreal Editor with I think all RDP for Linux soo unsure how related things are to what Im see :)

icculus commented 1 year ago

So just to be clear: is there something we can do here? Or is this strictly a TigerVNC (and/or other VNC servers) issue at this point?

If there's some reasonable way to decide we're being giving absolute coords when it thinks we're getting relative coords, we can put a check in there for that, but I'm not sure how to detect that.

mika314 commented 1 year ago

I have this issue with the Wacom tablet.

Also, I noticed Virtual Box, by default, sets Pointing Device to USB Tablet. I am wondering if switching to the mouse may fix the SDL issue.

image

BrandonSchaefer commented 1 year ago

I've not fully dug enough in to say, and I've only spotted what looks to be an issue with the x11 server and how the mouse devices are being faked through xinput. With regards to TightVNC, Im quite rusty now with x11 but it really seems like something is either not implemented (xinput2 interface, while they say they support it, the devices say they are relative, but return absolute cords... which seems like a bug in the server implementation they are using)

I need to double check, but even though its saying relative, I have a fear/guess that if you hit the edge of a window these events stop reporting. If this is the case, we really cannot work around much here sadly :( ... even faking it using the last known x/y, if no even when pushing right, or even if an event our x/y position against the edge of the window will be the same as the last giving us a 0 +/- :(

Still needs more debugging but its ... quite annoying to debug x11 + remote setups :)