[PATCH libinput] touchpad: disable 2fg scrolling on semi-mt touchpads
Peter Hutterer
peter.hutterer at who-t.net
Mon Jul 13 20:39:15 PDT 2015
These touchpads have a terrible resolution when two fingers are down, causing
scrolling to jump around a lot. That then turns into bug reports that we can't
do much about, the data is simply garbage.
For Alps:
https://bugs.freedesktop.org/show_bug.cgi?id=91081
For Synaptics:
https://bugs.freedesktop.org/show_bug.cgi?id=91135
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
doc/scrolling.dox | 7 +++++++
src/evdev-mt-touchpad.c | 35 ++++++++++++++++++++++++++++-------
test/touchpad.c | 23 +++++++++++++----------
3 files changed, 48 insertions(+), 17 deletions(-)
diff --git a/doc/scrolling.dox b/doc/scrolling.dox
index 658fe4b..10f5331 100644
--- a/doc/scrolling.dox
+++ b/doc/scrolling.dox
@@ -44,6 +44,13 @@ movements will translate into tiny scroll movements.
Scrolling in both directions at once is possible by meeting the required
distance thresholds to enable each direction separately.
+Two-finger scrolling requires the touchpad to track both touch points with
+reasonable precision. Unfortunately, so-called "semi-mt" touchpads can only
+track the bounding box of the two fingers rather than the actual position of
+each finger. In addition, that bounding box usually suffers from a
+low resolution, causing jumpy movement during two-finger scrolling. libinput
+does not provide two-finger scrolling on those touchpads.
+
@section edge_scrolling Edge scrolling
On some touchpads, edge scrolling is available, triggered by moving a single
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index bbba665..4ab57f2 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -1370,18 +1370,27 @@ tp_init_accel(struct tp_dispatch *tp, double diagonal)
}
static uint32_t
-tp_scroll_config_scroll_method_get_methods(struct libinput_device *device)
+tp_scroll_get_methods(struct tp_dispatch *tp)
{
- struct evdev_device *evdev = (struct evdev_device*)device;
- struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
uint32_t methods = LIBINPUT_CONFIG_SCROLL_EDGE;
- if (tp->ntouches >= 2)
+ /* semi-mt touchpads have a terrible 2fg resolution, causing
+ * scroll jumps */
+ if (tp->ntouches >= 2 && !tp->semi_mt)
methods |= LIBINPUT_CONFIG_SCROLL_2FG;
return methods;
}
+static uint32_t
+tp_scroll_config_scroll_method_get_methods(struct libinput_device *device)
+{
+ struct evdev_device *evdev = (struct evdev_device*)device;
+ struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
+
+ return tp_scroll_get_methods(tp);
+}
+
static enum libinput_config_status
tp_scroll_config_scroll_method_set_method(struct libinput_device *device,
enum libinput_config_scroll_method method)
@@ -1413,10 +1422,22 @@ tp_scroll_config_scroll_method_get_method(struct libinput_device *device)
static enum libinput_config_scroll_method
tp_scroll_get_default_method(struct tp_dispatch *tp)
{
- if (tp->ntouches >= 2)
- return LIBINPUT_CONFIG_SCROLL_2FG;
+ uint32_t methods;
+ enum libinput_config_scroll_method method;
+
+ methods = tp_scroll_get_methods(tp);
+
+ if (tp->ntouches >= 2 &&
+ (methods & LIBINPUT_CONFIG_SCROLL_2FG))
+ method = LIBINPUT_CONFIG_SCROLL_2FG;
else
- return LIBINPUT_CONFIG_SCROLL_EDGE;
+ method = LIBINPUT_CONFIG_SCROLL_EDGE;
+
+ if ((methods & method) == 0)
+ log_bug_libinput(tp_libinput_context(tp),
+ "Invalid default scroll method %d\n",
+ method);
+ return method;
}
static enum libinput_config_scroll_method
diff --git a/test/touchpad.c b/test/touchpad.c
index 7058bea..78eb022 100644
--- a/test/touchpad.c
+++ b/test/touchpad.c
@@ -1530,7 +1530,7 @@ START_TEST(touchpad_scroll_natural_enable_config)
}
END_TEST
-START_TEST(touchpad_scroll_natural)
+START_TEST(touchpad_scroll_natural_2fg)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
@@ -1603,10 +1603,12 @@ START_TEST(touchpad_scroll_defaults)
method = libinput_device_config_scroll_get_methods(device);
ck_assert(method & LIBINPUT_CONFIG_SCROLL_EDGE);
- if (libevdev_get_num_slots(evdev) > 1)
+ if (libevdev_get_num_slots(evdev) > 1 &&
+ !libevdev_has_property(evdev, INPUT_PROP_SEMI_MT))
ck_assert(method & LIBINPUT_CONFIG_SCROLL_2FG);
- if (libevdev_get_num_slots(evdev) > 1)
+ if (libevdev_get_num_slots(evdev) > 1 &&
+ !libevdev_has_property(evdev, INPUT_PROP_SEMI_MT))
expected = LIBINPUT_CONFIG_SCROLL_2FG;
else
expected = LIBINPUT_CONFIG_SCROLL_EDGE;
@@ -1622,7 +1624,8 @@ START_TEST(touchpad_scroll_defaults)
status = libinput_device_config_scroll_set_method(device,
LIBINPUT_CONFIG_SCROLL_2FG);
- if (libevdev_get_num_slots(evdev) > 1)
+ if (libevdev_get_num_slots(evdev) > 1 &&
+ !libevdev_has_property(evdev, INPUT_PROP_SEMI_MT))
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
else
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
@@ -4187,14 +4190,14 @@ litest_setup_tests(void)
litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_clickfinger, LITEST_TOPBUTTONPAD, LITEST_ANY);
litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_clickfinger_dev_disabled, LITEST_TOPBUTTONPAD, LITEST_ANY);
- litest_add("touchpad:scroll", touchpad_2fg_scroll, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
- litest_add("touchpad:scroll", touchpad_2fg_scroll_slow_distance, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
- litest_add("touchpad:scroll", touchpad_2fg_scroll_return_to_motion, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
- litest_add("touchpad:scroll", touchpad_2fg_scroll_source, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
- litest_add("touchpad:scroll", touchpad_2fg_scroll_semi_mt, LITEST_SEMI_MT, LITEST_SINGLE_TOUCH);
+ litest_add("touchpad:scroll", touchpad_2fg_scroll, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
+ litest_add("touchpad:scroll", touchpad_2fg_scroll_slow_distance, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
+ litest_add("touchpad:scroll", touchpad_2fg_scroll_return_to_motion, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
+ litest_add("touchpad:scroll", touchpad_2fg_scroll_source, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
+ litest_add("touchpad:scroll", touchpad_2fg_scroll_semi_mt, LITEST_SEMI_MT, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add("touchpad:scroll", touchpad_scroll_natural_defaults, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:scroll", touchpad_scroll_natural_enable_config, LITEST_TOUCHPAD, LITEST_ANY);
- litest_add("touchpad:scroll", touchpad_scroll_natural, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
+ litest_add("touchpad:scroll", touchpad_scroll_natural_2fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add("touchpad:scroll", touchpad_scroll_defaults, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:scroll", touchpad_edge_scroll, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:scroll", touchpad_edge_scroll_no_motion, LITEST_TOUCHPAD, LITEST_ANY);
--
2.4.3
More information about the wayland-devel
mailing list