ValveSoftware / gamescope

SteamOS session compositing window manager
Other
3.14k stars 212 forks source link

--mouse-sensitivity or -s introduces a dead range. #1521

Open Gibitwit opened 2 months ago

Gibitwit commented 2 months ago

I was excited to see that --mouse-sensitivity now works. But it adds a hefty dead range to mouse movement. The view will not move at all without a good amount of movement of the mouse in a short time. This makes --mouse-sensitivity option useless. I suppose it does not actually scale mouse tracking but throws out counts instead.

Please eliminate the dead range.

hfc2x commented 1 month ago

What game are you playing? What did you set the sensitivity to? Those details are kind of too important to be left out lol.

Gibitwit commented 1 month ago

Shadow Warrior 3. Gamescope sensitivity set to 0.922. For Shadow Warrior 3 I also had to use Force grab cursor.

Star Wars Battlefront 2 2005 with Gamescope sensitivity set to 0.8586.

laurirasanen commented 1 month ago

It would seem that zwp_relative_pointer_v1_send_relative_motion does nothing with dx_unaccel and dy_unaccel values less than 1.

Maybe not a proper fix but could hack together accumulation by doing something like:

--- a/src/wlserver.cpp
+++ b/src/wlserver.cpp
@@ -2335,2 +2335,4 @@ static bool wlserver_apply_constraint( double *dx, double *dy )

+static double rem_x = 0.0;
+static double rem_y = 0.0;
 void wlserver_mousemotion( double dx, double dy, uint32_t time )
@@ -2342,2 +2344,10 @@ void wlserver_mousemotion( double dx, double dy, uint32_t time )

+       dx += rem_x;
+       dy += rem_y;
+       rem_x = fmod(dx,  1.0);
+       rem_y = fmod(dy,  1.0);
+       dx -= rem_x;
+       dy -= rem_y;
+       if (abs(dx) <= 0 && abs(dy) <= 0) return;
+
        wlserver_perform_rel_pointer_motion( dx, dy );

Also https://github.com/ValveSoftware/gamescope/issues/1371 maybe related.

tobiasjakobi commented 1 month ago

@laurirasanen Is this behaviour documented somewhere? I had a look at the spec, but the only thing I can see there is that the deltas are transmitted as fixed point. So it has of course happen, that e.g. if dx is very small (as double), then after the fixed point conversion it becomes zero. But that would mean dx needs to be smaller than 1.0 / 256.0. Is this usually the case here?

laurirasanen commented 1 month ago

@tobiasjakobi Not sure, but I can repro the issue if the double value is less than 1.0.

Tested with on Plasma X11 with:

And on Plasma Wayland with:

All running a 3D application that uses SDL2 for windowing if that matters.

The double values aren't so small that the conversion would break. Doing wl_fixed_to_double(wl_fixed_from_double(x)) still produces reasonable values within 1/512 of the original.

laurirasanen commented 1 month ago

Seems that the issue happens specifically with applications that use SDL_SetRelativeMouseMode(SDL_TRUE).

In relative mode SDL_MOUSEMOTION events wont be triggered in the application unless one of the deltas in wlserver_mousemotion is >= 1.0.

Made a minimal repro here: https://github.com/laurirasanen/sdl-gamescope-1521

Running the repro in gamescope with a patch for printing the sent values:

--- a/src/wlserver.cpp
+++ b/src/wlserver.cpp
@@ -2339,6 +2339,7 @@ void wlserver_mousemotion( double dx, double dy, uint32_t time )

        dx *= g_mouseSensitivity;
        dy *= g_mouseSensitivity;
+       printf("dx %f dy %f\n", dx, dy);

Will log, for example:

dx 0.200000 dy 0.600000
dx 0.100000 dy 0.600000
dx 0.200000 dy 0.700000
dx 0.200000 dy 0.700000
dx 0.300000 dy 0.800000
dx 0.300000 dy 0.700000
dx 0.300000 dy 0.800000
dx 0.500000 dy 1.000000
SDL_MOUSEMOTION 0 1
dx 0.500000 dy 1.100000
SDL_MOUSEMOTION 0 1
dx 0.600000 dy 1.000000
SDL_MOUSEMOTION 0 1
dx 0.800000 dy 1.300000
SDL_MOUSEMOTION 0 1
dx 0.700000 dy 1.300000
SDL_MOUSEMOTION 0 1
dx 0.900000 dy 1.300000
SDL_MOUSEMOTION 0 1
dx 0.900000 dy 1.300000
SDL_MOUSEMOTION 0 1
dx 1.100000 dy 1.500000
SDL_MOUSEMOTION 1 1
dx 1.200000 dy 1.700000
SDL_MOUSEMOTION 1 1
dx 1.200000 dy 1.500000
SDL_MOUSEMOTION 1 1
dx 1.800000 dy 2.100000
SDL_MOUSEMOTION 1 2
tobiasjakobi commented 2 weeks ago

@laurirasanen I've checked some of the games that I have mouse issues with, and Wolfenstein 2 appears to have the exact same problem: https://github.com/ValveSoftware/gamescope/issues/1560#issuecomment-2440040670

Applying this integer coordinate buffering workaround makes things working there.