RFC libinput high-resolution wheel scrolling

Peter Hutterer peter.hutterer at who-t.net
Fri Jan 25 05:27:47 UTC 2019


I'm sending this here to get some more exposure. The kernel will get
high-resolution scroll wheels with the 5.0 release. The details are in the
blog post linked below [1], but the short summary is that we now get
REL_WHEEL for full clicks and REL_WHEEL_HI_RES for fine-grained events.

The units REL_WHEEL_HI_RES are: 120 is one logical wheel click, a fraction
thereof indicates a wheel movement by that. The 120 value comes from the
Windows Vista API btw.

So an event sequence for a 20 degree wheel movement on my Logitech MX
Anywhere 2S is this:

EV_REL REL_WHEEL_HI_RES 15
EV_SYN SYN_REPORT
EV_REL REL_WHEEL_HI_RES 15
EV_SYN SYN_REPORT
EV_REL REL_WHEEL_HI_RES 15
EV_SYN SYN_REPORT
EV_REL REL_WHEEL_HI_RES 15
EV_SYN SYN_REPORT
EV_REL REL_WHEEL_HI_RES 15
EV_SYN SYN_REPORT
EV_REL REL_WHEEL_HI_RES 15
EV_SYN SYN_REPORT
EV_REL REL_WHEEL_HI_RES 15
EV_SYN SYN_REPORT
EV_REL REL_WHEEL_HI_RES 15
EV_REL REL_WHEEL 1
EV_SYN SYN_REPORT

In short, we get 7 event frames with hi-res only, then one frame with both
hi-res and the low-res event.

libinput's API has libinput_event_pointer_axis_get_value() and
libinput_event_pointer_axis_get_value_discrete(). For wheel events, the
former returns the rotation angle, the latter the number of logical clicks.
Currently, this means you'd get e.g. 15/1 for most mice, or 20/1 for some
others. With the kernel above, you now get 7 events with 2.5/0, one event
with 2.5/1, i.e. the value must be accumulated if you want click-based
scrolling (this is already the case for non-wheel scroll events).

I tried integrating this into the xf86-input-libinput driver and it was...
tricky. That driver needs to know everyhing ahead of time but with the
current API you don't know the full click angle until you get the first
discrete event. AFAICT, both mutter and weston would have similar issues
when adding the above.

The solution I came up with, see [2], is to forward the 120 value with a new
API: libinput_pointer_axis_get_value_v120()

For the MX Anywhere 2S, each event thus now gives me three values:
7 events with 2.5/0/15 and 1 event with 2.5/1/15.

For the caller, this means:
- easy enough to calculate the click angle from the first event where needed
  (no generic caller actually cares about this though, it's a rather
  specialised case).
- easy to do click-angle-independent pointer movement

Seems to be easy to integrate into weston/mutter. There shouldn't be any
need for wayland protocol updates either, we can just do the fraction of the
movement so instead of 10 per event, we now send 10/120 * v120 value. So we
need the compositors to handle a new API, but at least the wayland client
side doesn't change.

Any comments? Anything I've overlooked?

Cheers,
   Peter

[1] https://who-t.blogspot.com/2018/12/high-resolution-wheel-scrolling-on.html
[2] https://gitlab.freedesktop.org/libinput/libinput/merge_requests/139



More information about the wayland-devel mailing list