scrcpy
scrcpy copied to clipboard
Handle high-precision scrolling when using notebook touchpads
- [x] I have checked that a similar feature request does not already exist.
Is your feature request related to a problem? Please describe. I'm investigating yume-chan/ya-webadb#396, a user reported that the scrolling speed of my client implementation, when using notebook touchpads, is super fast.
It turns out that Scrcpy is using the integer scrolling distances (x
, y
) from SDL, but mouse wheel events from browsers only contains high-resolution distances (and the event is firing very frequently). It's pretty hard to emulate integer scrolling distances from fractional ones,
In my testing using the native Scrcpy client with a notebook touchpad, the two-fingering scrolling works, but feels clunky.
https://user-images.githubusercontent.com/1330321/177030433-d060a577-0930-4788-a40a-ced0bfb37e9a.mp4
Describe the solution you'd like
Since SDL also provides high-resolution scrolling distances (preciseX
and preciseY
in SDL_MouseWheelEvent), and Android accepts float values in MotionEvent.PointerCoords.setAxisValue, switch Scrcpy to use the high-precision ones. This will make scrolling on notebook touchpad super smooth.
Additional context
I tested the idea on https://github.com/Genymobile/scrcpy/compare/master...yume-chan:scrcpy:float-scroll. The result on Windows laptops is good.
https://user-images.githubusercontent.com/1330321/177030443-51cd73d8-c80d-4984-98ff-c63213d3d33a.mp4
Logged SDL mouse wheel events:
scroll x=0, y=-1, preciseX=0, preciseY=-1.38333
scroll x=0, y=0, preciseX=0, preciseY=-0.566667
scroll x=0, y=-1, preciseX=0, preciseY=-0.775
scroll x=0, y=-1, preciseX=0, preciseY=-0.541667
scroll x=0, y=-1, preciseX=0, preciseY=-0.808333
scroll x=0, y=0, preciseX=0, preciseY=-0.708333
scroll x=0, y=-1, preciseX=0, preciseY=-0.641667
scroll x=0, y=-1, preciseX=0, preciseY=-0.791667
scroll x=0, y=0, preciseX=0, preciseY=-0.458333
scroll x=0, y=-1, preciseX=0, preciseY=-0.7
scroll x=0, y=0, preciseX=0, preciseY=-0.233333
scroll x=0, y=0, preciseX=0, preciseY=-0.316667
scroll x=0, y=-1, preciseX=0, preciseY=-0.25
scroll x=0, y=0, preciseX=0, preciseY=-0.0916667
scroll x=0, y=0, preciseX=0, preciseY=-0.05
scroll x=0, y=0, preciseX=0, preciseY=-0.0416667
scroll x=0, y=0, preciseX=0, preciseY=-0.025
scroll x=0, y=0, preciseX=0, preciseY=-0.00833333
scroll x=0, y=0, preciseX=0, preciseY=-0.00833333
scroll x=0, y=0, preciseX=0, preciseY=-0.00833333
scroll x=0, y=0, preciseX=0, preciseY=0.00833333
scroll x=0, y=0, preciseX=0, preciseY=0.00833333
scroll x=0, y=0, preciseX=0, preciseY=0.0166667
scroll x=0, y=0, preciseX=0, preciseY=0.0666667
scroll x=0, y=0, preciseX=0, preciseY=0.191667
scroll x=0, y=0, preciseX=0, preciseY=0.2
scroll x=0, y=0, preciseX=0, preciseY=0.391667
scroll x=0, y=1, preciseX=0, preciseY=0.325
scroll x=0, y=0, preciseX=0, preciseY=0.625
scroll x=0, y=1, preciseX=0, preciseY=0.7
scroll x=0, y=1, preciseX=0, preciseY=0.841667
scroll x=0, y=1, preciseX=0, preciseY=0.666667
scroll x=0, y=0, preciseX=0, preciseY=0.808333
scroll x=0, y=1, preciseX=0, preciseY=0.75
scroll x=0, y=1, preciseX=0, preciseY=0.516667
scroll x=0, y=0, preciseX=0, preciseY=0.783333
scroll x=0, y=1, preciseX=0, preciseY=0.433333
scroll x=0, y=0, preciseX=0, preciseY=0.6
scroll x=0, y=1, preciseX=0, preciseY=0.308333
scroll x=0, y=0, preciseX=0, preciseY=0.15
scroll x=0, y=0, preciseX=0, preciseY=0.6
scroll x=0, y=1, preciseX=0, preciseY=0.0833333
scroll x=0, y=0, preciseX=0, preciseY=0.0916667
scroll x=0, y=0, preciseX=0, preciseY=0.05
scroll x=0, y=0, preciseX=0, preciseY=0.0333333
scroll x=0, y=0, preciseX=0, preciseY=0.00833333
scroll x=0, y=0, preciseX=0, preciseY=0.00833333
scroll x=0, y=0, preciseX=0, preciseY=0.00833333
The value can exceed 1/-1 when scrolling fast, but looks like Android only accepts value between -1 and 1
Thank you for the report :+1: A PR is welcome :wink:
Some first remarks on your branch.
The preciseX
/preciseY
fields have been added in SDL 2.0.18, so a fallback method using x
and y
must be kept (using SDL_VERSION_ATLEAST(2, 0, 18)
).
The vscroll
and hscroll
in struct sc_mouse_scroll_event
should be float
s, and serialized as fixed point values (cf how pressure is handled).
OK. Should I also clamp the value to -1~1 and/or shorten the fields to 16 bits (short) each like pressure? The documentation of MotionEvent.AXIS_HSCROLL
(https://developer.android.com/reference/android/view/MotionEvent#AXIS_HSCROLL) says the range is -1 to 1.
Should I also clamp the value to -1~1
I think so.
and/or shorten the fields to 16 bits (short) each like pressure?
I would say yes, I guess 16 bits is sufficient (and for consistency with pressure).
Fixed by #3369.