[PATCH libinput] touchpad: disable 2fg scrolling on semi-mt touchpads

Hans de Goede hdegoede at redhat.com
Tue Jul 21 13:15:24 PDT 2015


Hi,

On 07/16/2015 01:55 AM, Peter Hutterer wrote:
> 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.

Right, that is what I was about to say, atleast for alps semi-mt 2fg
scrolling should work fine with the recent kernel + libinput patches.

I think the bug reports your wrote this series for were actually mostly
for people with alps devices who do not yet have the kernel fixes.

Regards,

Hans


>
> 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
> _______________________________________________
> 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