Add support for high-resolution wheel scrolling

This commit is contained in:
Peter Hutterer 2021-09-03 09:33:11 +10:00
parent fc23da9a04
commit b6d27861d8
4 changed files with 366 additions and 1 deletions

View File

@ -0,0 +1,56 @@
From bf8dc2e2ed0780b947eccfc9ac3694c518dee605 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Wed, 23 Jan 2019 09:01:24 +1000
Subject: [PATCH xf86-input-libinput 1/3] Upgrade the default scroll distance
to 120
This is just a number, to be used as divider and shouldn't have any effect in
correctly written clients. With the high-res scrolling coming up however, we
have a few devices where the dist cannot be expressed as an integer fraction
of 15, so let's up it to 120 because we know all hardware wheels have to be an
integer fraction of that that, thanks to Microsoft's API requirements.
For non-wheel scrolls we need to now map into the new range. Previously we
just passed the scroll events on from the touchpad/button scrolling, meaning a
vdist of 15 meant 15 "libinput pixels" of scrolling resulted in a logical
wheel click. Now that we have 120 as vdist, we need to times the input data by
8 to keep the same proportions.
See 39b0bb4585106a56a51236d8e9843b2da8d745a5 for the previous revert.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
src/xf86libinput.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/src/xf86libinput.c b/src/xf86libinput.c
index 33b02da..adbc724 100644
--- a/src/xf86libinput.c
+++ b/src/xf86libinput.c
@@ -1652,8 +1652,11 @@ calculate_axis_value(struct xf86libinput *driver_data,
* device. The user may change the ScrollPixelDistance
* though, so where we have a dist of 10 but an increment of
* 15, we need to scale from 0..10 into 0..15.
+ *
+ * We now switched to vdist of 120, so make this
+ * proportionate - 120/15 is 8.
*/
- value = value/dist * SCROLL_INCREMENT;
+ value = value/dist * SCROLL_INCREMENT * 8;
}
*value_out = value;
@@ -3585,8 +3588,8 @@ xf86libinput_pre_init(InputDriverPtr drv,
* affect touchpad scroll speed. For wheels it doesn't matter as
* we're using the discrete value only.
*/
- driver_data->scroll.v.dist = SCROLL_INCREMENT;
- driver_data->scroll.h.dist = SCROLL_INCREMENT;
+ driver_data->scroll.v.dist = 120;
+ driver_data->scroll.h.dist = 120;
if (!is_subdevice) {
if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER))
--
2.31.1

View File

@ -0,0 +1,91 @@
From ca9042c7f08f8f0dc214b9cc19f3243728ec8c4a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= <jose.exposito89@gmail.com>
Date: Wed, 4 Aug 2021 17:51:26 +0200
Subject: [PATCH xf86-input-libinput 2/3] Get scroll source in the event
handler
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Where libinput supports high-resolution scroll events, the scroll source
is encoded in the event type.
Get the scroll source in xf86libinput_handle_event to facilitate the
migration.
Refactor, no functional changes.
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
---
src/xf86libinput.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/xf86libinput.c b/src/xf86libinput.c
index adbc724..a8b7013 100644
--- a/src/xf86libinput.c
+++ b/src/xf86libinput.c
@@ -1631,15 +1631,14 @@ static inline bool
calculate_axis_value(struct xf86libinput *driver_data,
enum libinput_pointer_axis axis,
struct libinput_event_pointer *event,
+ enum libinput_pointer_axis_source source,
double *value_out)
{
- enum libinput_pointer_axis_source source;
double value;
if (!libinput_event_pointer_has_axis(event, axis))
return false;
- source = libinput_event_pointer_get_axis_source(event);
if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL) {
value = get_wheel_scroll_value(driver_data, event, axis);
} else {
@@ -1665,7 +1664,9 @@ calculate_axis_value(struct xf86libinput *driver_data,
}
static void
-xf86libinput_handle_axis(InputInfoPtr pInfo, struct libinput_event_pointer *event)
+xf86libinput_handle_axis(InputInfoPtr pInfo,
+ struct libinput_event_pointer *event,
+ enum libinput_pointer_axis_source source)
{
DeviceIntPtr dev = pInfo->dev;
struct xf86libinput *driver_data = pInfo->private;
@@ -1678,7 +1679,6 @@ xf86libinput_handle_axis(InputInfoPtr pInfo, struct libinput_event_pointer *even
valuator_mask_zero(mask);
- source = libinput_event_pointer_get_axis_source(event);
switch(source) {
case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
@@ -1691,6 +1691,7 @@ xf86libinput_handle_axis(InputInfoPtr pInfo, struct libinput_event_pointer *even
if (calculate_axis_value(driver_data,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
event,
+ source,
&value))
valuator_mask_set_double(mask, 3, value);
@@ -1700,6 +1701,7 @@ xf86libinput_handle_axis(InputInfoPtr pInfo, struct libinput_event_pointer *even
if (calculate_axis_value(driver_data,
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
event,
+ source,
&value))
valuator_mask_set_double(mask, 2, value);
@@ -2381,7 +2383,8 @@ xf86libinput_handle_event(struct libinput_event *event)
break;
case LIBINPUT_EVENT_POINTER_AXIS:
xf86libinput_handle_axis(pInfo,
- libinput_event_get_pointer_event(event));
+ libinput_event_get_pointer_event(event),
+ libinput_event_pointer_get_axis_source(event));
break;
case LIBINPUT_EVENT_TOUCH_FRAME:
break;
--
2.31.1

View File

@ -0,0 +1,210 @@
From beb94333e1450006942a7f0ee38bc2a2f5719238 Mon Sep 17 00:00:00 2001
From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Wed, 23 Jan 2019 20:07:37 +1000
Subject: [PATCH xf86-input-libinput 3/3] Use the new v120 API from libinput if
available
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
configure.ac | 12 ++++++
src/xf86libinput.c | 105 ++++++++++++++++++++++++++++++++++++++-------
2 files changed, 101 insertions(+), 16 deletions(-)
diff --git a/configure.ac b/configure.ac
index 176d22e..f747a3d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,6 +62,18 @@ AC_LINK_IFELSE(
[libinput_have_scroll_button_lock=yes]],
[AC_MSG_RESULT([no])
[libinput_have_scroll_button_lock=no]])
+
+AC_MSG_CHECKING([if libinput_event_pointer_get_scroll_value_v120 is available])
+AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([[#include <libinput.h>]],
+ [[libinput_event_pointer_get_scroll_value_v120(NULL, 0)]])],
+ [AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_LIBINPUT_AXIS_VALUE_V120, [1],
+ [libinput_event_pointer_get_scroll_value_v120() is available])
+ [libinput_have_axis_value_v120=yes]],
+ [AC_MSG_RESULT([no])
+ [libinput_have_axis_value_v120=no]])
+
LIBS=$OLD_LIBS
CFLAGS=$OLD_CFLAGS
diff --git a/src/xf86libinput.c b/src/xf86libinput.c
index a8b7013..0cb0c3c 100644
--- a/src/xf86libinput.c
+++ b/src/xf86libinput.c
@@ -1565,9 +1565,9 @@ xf86libinput_handle_key(InputInfoPtr pInfo, struct libinput_event_keyboard *even
* so the use-case above shouldn't matter anymore.
*/
static inline double
-get_wheel_scroll_value(struct xf86libinput *driver_data,
- struct libinput_event_pointer *event,
- enum libinput_pointer_axis axis)
+guess_wheel_scroll_value(struct xf86libinput *driver_data,
+ struct libinput_event_pointer *event,
+ enum libinput_pointer_axis axis)
{
struct scroll_axis *s;
double f;
@@ -1627,6 +1627,54 @@ out:
return s->dist/s->fraction * discrete;
}
+#if HAVE_LIBINPUT_AXIS_VALUE_V120
+static inline double
+get_wheel_120_value(struct xf86libinput *driver_data,
+ struct libinput_event_pointer *event,
+ enum libinput_pointer_axis axis)
+{
+ struct scroll_axis *s;
+ double angle;
+
+ switch (axis) {
+ case LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL:
+ s = &driver_data->scroll.h;
+ break;
+ case LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL:
+ s = &driver_data->scroll.v;
+ break;
+ default:
+ return 0.0;
+ }
+
+ angle = libinput_event_pointer_get_scroll_value_v120(event, axis);
+ return s->dist * angle/120;
+}
+#endif
+
+static inline double
+get_wheel_scroll_value(struct xf86libinput *driver_data,
+ struct libinput_event_pointer *event,
+ enum libinput_pointer_axis axis)
+{
+#if HAVE_LIBINPUT_AXIS_VALUE_V120
+ return get_wheel_120_value(driver_data, event, axis);
+#else
+ return guess_wheel_scroll_value(driver_data, event, axis);
+#endif
+}
+
+static inline double
+get_finger_or_continuous_scroll_value(struct libinput_event_pointer *event,
+ enum libinput_pointer_axis axis)
+{
+#if HAVE_LIBINPUT_AXIS_VALUE_V120
+ return libinput_event_pointer_get_scroll_value(event, axis);
+#else
+ return libinput_event_pointer_get_axis_value(event, axis);
+#endif
+}
+
static inline bool
calculate_axis_value(struct xf86libinput *driver_data,
enum libinput_pointer_axis axis,
@@ -1639,13 +1687,21 @@ calculate_axis_value(struct xf86libinput *driver_data,
if (!libinput_event_pointer_has_axis(event, axis))
return false;
+ /* Event may be LIBINPUT_POINTER_AXIS or
+ * LIBINPUT_EVENT_POINTER_SCROLL_{WHEEL|FINGER|CONTINUOUS}, depending
+ * on the libinput version.
+ *
+ * libinput guarantees the axis source is set for the second set of
+ * events too but we can switch to the event type once we ditch
+ * libinput < 1.19 support.
+ */
if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL) {
value = get_wheel_scroll_value(driver_data, event, axis);
} else {
double dist = driver_data->options.scroll_pixel_distance;
assert(dist != 0.0);
- value = libinput_event_pointer_get_axis_value(event, axis);
+ value = get_finger_or_continuous_scroll_value(event, axis);
/* We need to scale this value into our scroll increment range
* because that one is constant for the lifetime of the
* device. The user may change the ScrollPixelDistance
@@ -1665,29 +1721,21 @@ calculate_axis_value(struct xf86libinput *driver_data,
static void
xf86libinput_handle_axis(InputInfoPtr pInfo,
- struct libinput_event_pointer *event,
+ struct libinput_event *e,
enum libinput_pointer_axis_source source)
{
+ struct libinput_event_pointer *event;
DeviceIntPtr dev = pInfo->dev;
struct xf86libinput *driver_data = pInfo->private;
ValuatorMask *mask = driver_data->valuators;
double value;
- enum libinput_pointer_axis_source source;
if ((driver_data->capabilities & CAP_POINTER) == 0)
return;
valuator_mask_zero(mask);
- switch(source) {
- case LIBINPUT_POINTER_AXIS_SOURCE_FINGER:
- case LIBINPUT_POINTER_AXIS_SOURCE_WHEEL:
- case LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS:
- break;
- default:
- return;
- }
-
+ event = libinput_event_get_pointer_event(e);
if (calculate_axis_value(driver_data,
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
event,
@@ -1705,6 +1753,11 @@ xf86libinput_handle_axis(InputInfoPtr pInfo,
&value))
valuator_mask_set_double(mask, 2, value);
+ if (source == LIBINPUT_POINTER_AXIS_SOURCE_WHEEL &&
+ !valuator_mask_isset(mask, 2) &&
+ !valuator_mask_isset(mask, 3))
+ return;
+
out:
xf86PostMotionEventM(dev, Relative, mask);
}
@@ -2382,10 +2435,30 @@ xf86libinput_handle_event(struct libinput_event *event)
libinput_event_get_keyboard_event(event));
break;
case LIBINPUT_EVENT_POINTER_AXIS:
+#if !HAVE_LIBINPUT_AXIS_VALUE_V120
+ /* ignore POINTER_AXIS where we have libinput 1.19 and higher */
xf86libinput_handle_axis(pInfo,
- libinput_event_get_pointer_event(event),
+ event,
libinput_event_pointer_get_axis_source(event));
+#endif
break;
+#if HAVE_LIBINPUT_AXIS_VALUE_V120
+ case LIBINPUT_EVENT_POINTER_SCROLL_WHEEL:
+ xf86libinput_handle_axis(pInfo,
+ event,
+ LIBINPUT_POINTER_AXIS_SOURCE_WHEEL);
+ break;
+ case LIBINPUT_EVENT_POINTER_SCROLL_FINGER:
+ xf86libinput_handle_axis(pInfo,
+ event,
+ LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
+ break;
+ case LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS:
+ xf86libinput_handle_axis(pInfo,
+ event,
+ LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
+ break;
+#endif
case LIBINPUT_EVENT_TOUCH_FRAME:
break;
case LIBINPUT_EVENT_TOUCH_UP:
--
2.31.1

View File

@ -8,7 +8,7 @@
Summary: Xorg X11 libinput input driver
Name: xorg-x11-drv-libinput
Version: 1.1.0
Release: 1%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
Release: 2%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist}
URL: http://www.x.org
License: MIT
@ -23,6 +23,11 @@ Source1: 71-libinput-overrides-wacom.conf
# https://bugzilla.redhat.com/show_bug.cgi?id=1413306
Patch01: 0001-Add-a-DPIScaleFactor-option-as-temporary-solution-to.patch
# High-resolution wheel scrolling (needs libinput 1.19)
Patch02: 0001-Upgrade-the-default-scroll-distance-to-120.patch
Patch03: 0002-Get-scroll-source-in-the-event-handler.patch
Patch04: 0003-Use-the-new-v120-API-from-libinput-if-available.patch
BuildRequires: make
BuildRequires: autoconf automake libtool
BuildRequires: xorg-x11-server-devel >= 1.14.0
@ -78,6 +83,9 @@ Xorg X11 libinput input driver development files.
%{_includedir}/xorg/libinput-properties.h
%changelog
* Fri Sep 03 2021 Peter Hutterer <peter.hutterer@redhat.com> - 1.1.0-2
- Add support for high-resolution wheel scrolling
* Fri Sep 03 2021 Peter Hutterer <peter.hutterer@redhat.com> - 1.1.0-1
- xf86-input-libinput 1.1.0