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

Peter Hutterer peter.hutterer at who-t.net
Tue Jul 14 17:13:07 PDT 2015


On Tue, Jul 14, 2015 at 01:39:15PM +1000, Peter Hutterer 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>
> ---

Hans, can you comment on this especially regarding the ALPS pads? I'm
tempted to do the same for gestures and just not enable them on semi-mt
touchpads. Do the ALPS all suffer from the resolution issues or are the
newer versions fine?

Cheers,
   Peter

>  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