From e7eafa199e9e60c15014a9d72d14efcbbf8e44ca Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 21 Jan 2019 15:21:45 +1000 Subject: Handle scroll wheel events with a discrete of 0 The driver currently assumes that any wheel event has a non-zero discrete value of 1. This is incorrect, it just hasn't triggered yet with any device. With the hi-res scroll patches in place in the kernel and libinput, we may get wheel events with a discrete value of 0. We assume that if this ever happens, the device has some sensible click angle set so all we need to do is ignore the discrete 0 events and wait for the first discrete event to come. Also add an explanatory comment too to make it clear the calculation is only done once. Fixes #19 Signed-off-by: Peter Hutterer --- src/xf86libinput.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/xf86libinput.c b/src/xf86libinput.c index a3005ea..103e0a4 100644 --- a/src/xf86libinput.c +++ b/src/xf86libinput.c @@ -1564,6 +1564,10 @@ xf86libinput_handle_key(InputInfoPtr pInfo, struct libinput_event_keyboard *even * e.g. a 2 degree click angle requires 8 clicks before a legacy event is * sent, but each of those clicks will send XI2.1 smooth scroll data for * compatible clients. + * + * Starting with kernel v5.0 we should get REL_WHEEL_HI_RES from those + * devices for the fine-grained scrolling and REL_WHEEL for the normal one, + * so the use-case above shouldn't matter anymore. */ static inline double get_wheel_scroll_value(struct xf86libinput *driver_data, @@ -1589,9 +1593,22 @@ get_wheel_scroll_value(struct xf86libinput *driver_data, angle = libinput_event_pointer_get_axis_value(event, axis); discrete = libinput_event_pointer_get_axis_value_discrete(event, axis); + /* We only need to guess the fraction on the first set of + * scroll events until a discrete value arrives. Once known, we + * re-use the fraction until the device goes away. + */ if (s->fraction != 0.0) goto out; + /* if we get a discrete of 0, assume REL_WHEEL_HI_RES exists and + * normal scroll events are sent correctly, so skip all the + * guesswork. + */ + if (discrete == 0) { + s->fraction = 1.0; + goto out; + } + /* Calculate the angle per single scroll event */ angle /= discrete; -- cgit v1.2.1