[PATCH libinput] touchpad: disable 2fg scrolling on semi-mt touchpads
Peter Hutterer
peter.hutterer at who-t.net
Wed Jul 15 16:55:46 PDT 2015
On Wed, Jul 15, 2015 at 11:44:47AM -0400, Benjamin Tissoires wrote:
> On Mon, Jul 13, 2015 at 11:39 PM, Peter Hutterer
> <peter.hutterer at who-t.net> wrote:
> > 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>
> > ---
>
> This patch is Acked-by: Benjamin Tissoires <benjamin.tissoires at gmail.com>
>
> FWIW, here is the list of semi-mt devices the kernel exports (and that
> will have 2 fg scrolling disabled by this patch):
>
> - Alps touchpads from firmware version 3 to 5 (6 seems to report
> single touch data anyway)
I just asked one user with a version 5 touchpad and that one seems to work
fine for 2fg scrolling after 07b20dcce6 "touchpad: Only use slot 0 deltas
for 2fg scrolling on semi-mt touchpads"
so looks like we need something finer-grained here anyway.
Cheers,
Peter
> - all Cypress PS/2 touchpads
> - Elantech touchpads from firmware version 2 to 3
> - the Sentelic touchpads that are reporting MT data
> - some early Synaptics touchpads with advanced gestures that are not
> image sensor
>
> Just brace yourself for users complaining about missing functionality :)
>
> Cheers,
> Benjamin
>
> > 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
> >
> > _______________________________________________
> > wayland-devel mailing list
> > wayland-devel at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list