summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2019-01-21 15:21:45 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2019-01-25 14:31:11 +1000
commite7eafa199e9e60c15014a9d72d14efcbbf8e44ca (patch)
tree9a9b66712ca03fc1a90f09c3e236e32c88d3fe24
parentd13ab268bdf6eb589022c58ddc87c1211b49ac4c (diff)
downloadxorg-driver-xf86-input-libinput-e7eafa199e9e60c15014a9d72d14efcbbf8e44ca.tar.gz
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 <peter.hutterer@who-t.net>
-rw-r--r--src/xf86libinput.c17
1 files changed, 17 insertions, 0 deletions
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;