Avoid erroneous finger movement after a physical click (#1230441)
This commit is contained in:
		
							parent
							
								
									be67c6dad6
								
							
						
					
					
						commit
						9d9abc12d4
					
				
							
								
								
									
										32
									
								
								0001-touchpad-fix-pinned-finger-drifting.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								0001-touchpad-fix-pinned-finger-drifting.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | From b48ecd186d8fb707e89bf04036a48600dc49125f Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Peter Hutterer <peter.hutterer@who-t.net> | ||||||
|  | Date: Fri, 12 Jun 2015 17:24:33 +1000 | ||||||
|  | Subject: [PATCH libinput] touchpad: fix pinned finger drifting | ||||||
|  | 
 | ||||||
|  | This caused the finger to be unpinned on the first motion event after the | ||||||
|  | click, effectively disabling this feature. | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> | ||||||
|  | Reviewed-by: Hans de Goede <hdegoede@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  src/evdev-mt-touchpad.c | 4 ++-- | ||||||
|  |  1 file changed, 2 insertions(+), 2 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
 | ||||||
|  | index c82d733..ce79530 100644
 | ||||||
|  | --- a/src/evdev-mt-touchpad.c
 | ||||||
|  | +++ b/src/evdev-mt-touchpad.c
 | ||||||
|  | @@ -440,8 +440,8 @@ tp_unpin_finger(struct tp_dispatch *tp, struct tp_touch *t)
 | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	/* The finger may slowly drift, adjust the center */ | ||||||
|  | -	t->pinned.center.x = t->point.x + t->pinned.center.x / 2;
 | ||||||
|  | -	t->pinned.center.y = t->point.y + t->pinned.center.y / 2;
 | ||||||
|  | +	t->pinned.center.x = (t->point.x + t->pinned.center.x)/2;
 | ||||||
|  | +	t->pinned.center.y = (t->point.y + t->pinned.center.y)/2;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  | -- 
 | ||||||
|  | 2.4.3 | ||||||
|  | 
 | ||||||
							
								
								
									
										194
									
								
								0001-touchpad-set-the-finger-pin-distance-to-5mm-where-po.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								0001-touchpad-set-the-finger-pin-distance-to-5mm-where-po.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,194 @@ | |||||||
|  | From 8025b374d564f4a30b089e5cf6fd65e0c6af8da2 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Peter Hutterer <peter.hutterer@who-t.net> | ||||||
|  | Date: Fri, 12 Jun 2015 17:29:41 +1000 | ||||||
|  | Subject: [PATCH libinput] touchpad: set the finger pin distance to 5mm where | ||||||
|  |  possible | ||||||
|  | 
 | ||||||
|  | On touchpads with resolutions, use a 5mm motion threshold before we unpin the | ||||||
|  | finger (allow motion events while a clickpad button is down). This should | ||||||
|  | remove any erroneous finger movements while clicking, at the cost of having to | ||||||
|  | move the finger a bit more for a single-finger click-and-drag (use two fingers | ||||||
|  | already!) | ||||||
|  | 
 | ||||||
|  | And drop the finger drifting, it was per-event based rather than time-based. | ||||||
|  | So unless the motion threshold was hit in a single event it was possible to | ||||||
|  | move the finger around the whole touchpad without ever unpinning it. | ||||||
|  | 
 | ||||||
|  | Drop the finger drifting altogether, if the touchpad drifts by more than 5mm | ||||||
|  | we have other issues. | ||||||
|  | 
 | ||||||
|  | https://bugzilla.redhat.com/show_bug.cgi?id=1230462 | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> | ||||||
|  | Reviewed-by: Hans de Goede <hdegoede@redhat.com> | ||||||
|  | ---
 | ||||||
|  |  src/evdev-mt-touchpad-buttons.c | 19 ++++++++++------ | ||||||
|  |  src/evdev-mt-touchpad.c         | 10 ++++----- | ||||||
|  |  src/evdev-mt-touchpad.h         |  5 ++++- | ||||||
|  |  src/libinput-util.h             |  6 ++++++ | ||||||
|  |  test/touchpad.c                 | 48 +++++++++++++++++++++++++++++++++++++++++ | ||||||
|  |  5 files changed, 75 insertions(+), 13 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
 | ||||||
|  | index 5786ea8..eb0ddcb 100644
 | ||||||
|  | --- a/src/evdev-mt-touchpad-buttons.c
 | ||||||
|  | +++ b/src/evdev-mt-touchpad-buttons.c
 | ||||||
|  | @@ -31,7 +31,6 @@
 | ||||||
|  |   | ||||||
|  |  #include "evdev-mt-touchpad.h" | ||||||
|  |   | ||||||
|  | -#define DEFAULT_BUTTON_MOTION_THRESHOLD 0.02 /* 2% of size */
 | ||||||
|  |  #define DEFAULT_BUTTON_ENTER_TIMEOUT 100 /* ms */ | ||||||
|  |  #define DEFAULT_BUTTON_LEAVE_TIMEOUT 300 /* ms */ | ||||||
|  |   | ||||||
|  | @@ -709,11 +708,19 @@ tp_init_buttons(struct tp_dispatch *tp,
 | ||||||
|  |  	absinfo_x = device->abs.absinfo_x; | ||||||
|  |  	absinfo_y = device->abs.absinfo_y; | ||||||
|  |   | ||||||
|  | -	width = abs(absinfo_x->maximum - absinfo_x->minimum);
 | ||||||
|  | -	height = abs(absinfo_y->maximum - absinfo_y->minimum);
 | ||||||
|  | -	diagonal = sqrt(width*width + height*height);
 | ||||||
|  | -
 | ||||||
|  | -	tp->buttons.motion_dist = diagonal * DEFAULT_BUTTON_MOTION_THRESHOLD;
 | ||||||
|  | +	/* pinned-finger motion threshold, see tp_unpin_finger.
 | ||||||
|  | +	   The MAGIC for resolution-less touchpads ends up as 2% of the diagonal */
 | ||||||
|  | +	if (device->abs.fake_resolution) {
 | ||||||
|  | +		const int BUTTON_MOTION_MAGIC = 0.007;
 | ||||||
|  | +		width = abs(absinfo_x->maximum - absinfo_x->minimum);
 | ||||||
|  | +		height = abs(absinfo_y->maximum - absinfo_y->minimum);
 | ||||||
|  | +		diagonal = sqrt(width*width + height*height);
 | ||||||
|  | +		tp->buttons.motion_dist.x_scale_coeff = diagonal * BUTTON_MOTION_MAGIC;
 | ||||||
|  | +		tp->buttons.motion_dist.y_scale_coeff = diagonal * BUTTON_MOTION_MAGIC;
 | ||||||
|  | +	} else {
 | ||||||
|  | +		tp->buttons.motion_dist.x_scale_coeff = 1.0/absinfo_x->resolution;
 | ||||||
|  | +		tp->buttons.motion_dist.y_scale_coeff = 1.0/absinfo_y->resolution;
 | ||||||
|  | +	}
 | ||||||
|  |   | ||||||
|  |  	tp->buttons.config_method.get_methods = tp_button_config_click_get_methods; | ||||||
|  |  	tp->buttons.config_method.set_method = tp_button_config_click_set_method; | ||||||
|  | diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
 | ||||||
|  | index ce79530..6f11599 100644
 | ||||||
|  | --- a/src/evdev-mt-touchpad.c
 | ||||||
|  | +++ b/src/evdev-mt-touchpad.c
 | ||||||
|  | @@ -431,17 +431,15 @@ tp_unpin_finger(struct tp_dispatch *tp, struct tp_touch *t)
 | ||||||
|  |  		return; | ||||||
|  |   | ||||||
|  |  	xdist = abs(t->point.x - t->pinned.center.x); | ||||||
|  | +	xdist *= tp->buttons.motion_dist.x_scale_coeff;
 | ||||||
|  |  	ydist = abs(t->point.y - t->pinned.center.y); | ||||||
|  | +	ydist *= tp->buttons.motion_dist.y_scale_coeff;
 | ||||||
|  |   | ||||||
|  | -	if (xdist * xdist + ydist * ydist >=
 | ||||||
|  | -			tp->buttons.motion_dist * tp->buttons.motion_dist) {
 | ||||||
|  | +	/* 3mm movement -> unpin */
 | ||||||
|  | +	if (vector_length(xdist, ydist) >= 3.0) {
 | ||||||
|  |  		t->pinned.is_pinned = false; | ||||||
|  |  		return; | ||||||
|  |  	} | ||||||
|  | -
 | ||||||
|  | -	/* The finger may slowly drift, adjust the center */
 | ||||||
|  | -	t->pinned.center.x = (t->point.x + t->pinned.center.x)/2;
 | ||||||
|  | -	t->pinned.center.y = (t->point.y + t->pinned.center.y)/2;
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void | ||||||
|  | diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
 | ||||||
|  | index fef5cb3..bd2d163 100644
 | ||||||
|  | --- a/src/evdev-mt-touchpad.h
 | ||||||
|  | +++ b/src/evdev-mt-touchpad.h
 | ||||||
|  | @@ -223,7 +223,10 @@ struct tp_dispatch {
 | ||||||
|  |  		bool click_pending; | ||||||
|  |  		uint32_t state; | ||||||
|  |  		uint32_t old_state; | ||||||
|  | -		uint32_t motion_dist;		/* for pinned touches */
 | ||||||
|  | +		struct {
 | ||||||
|  | +			double x_scale_coeff;
 | ||||||
|  | +			double y_scale_coeff;
 | ||||||
|  | +		} motion_dist;			/* for pinned touches */
 | ||||||
|  |  		unsigned int active;		/* currently active button, for release event */ | ||||||
|  |  		bool active_is_topbutton;	/* is active a top button? */ | ||||||
|  |   | ||||||
|  | diff --git a/src/libinput-util.h b/src/libinput-util.h
 | ||||||
|  | index 910406c..224e4b6 100644
 | ||||||
|  | --- a/src/libinput-util.h
 | ||||||
|  | +++ b/src/libinput-util.h
 | ||||||
|  | @@ -284,4 +284,10 @@ int parse_mouse_dpi_property(const char *prop);
 | ||||||
|  |  int parse_mouse_wheel_click_angle_property(const char *prop); | ||||||
|  |  double parse_trackpoint_accel_property(const char *prop); | ||||||
|  |   | ||||||
|  | +static inline double
 | ||||||
|  | +vector_length(double x, double y)
 | ||||||
|  | +{
 | ||||||
|  | +	return sqrt(x * x + y * y);
 | ||||||
|  | +}
 | ||||||
|  | +
 | ||||||
|  |  #endif /* LIBINPUT_UTIL_H */ | ||||||
|  | diff --git a/test/touchpad.c b/test/touchpad.c
 | ||||||
|  | index 692698c..1e5e97b 100644
 | ||||||
|  | --- a/test/touchpad.c
 | ||||||
|  | +++ b/test/touchpad.c
 | ||||||
|  | @@ -2153,6 +2153,53 @@ START_TEST(clickpad_click_n_drag)
 | ||||||
|  |  } | ||||||
|  |  END_TEST | ||||||
|  |   | ||||||
|  | +START_TEST(clickpad_finger_pin)
 | ||||||
|  | +{
 | ||||||
|  | +	struct litest_device *dev = litest_current_device();
 | ||||||
|  | +	struct libinput *li = dev->libinput;
 | ||||||
|  | +	struct libevdev *evdev = dev->evdev;
 | ||||||
|  | +	const struct input_absinfo *abs;
 | ||||||
|  | +
 | ||||||
|  | +	abs = libevdev_get_abs_info(evdev, ABS_MT_POSITION_X);
 | ||||||
|  | +	ck_assert_notnull(abs);
 | ||||||
|  | +	if (abs->resolution == 0)
 | ||||||
|  | +		return;
 | ||||||
|  | +
 | ||||||
|  | +	litest_drain_events(li);
 | ||||||
|  | +
 | ||||||
|  | +	/* make sure the movement generates pointer events when
 | ||||||
|  | +	   not pinned */
 | ||||||
|  | +	litest_touch_down(dev, 0, 50, 50);
 | ||||||
|  | +	litest_touch_move_to(dev, 0, 50, 50, 52, 52, 10, 1);
 | ||||||
|  | +	litest_touch_move_to(dev, 0, 52, 52, 48, 48, 10, 1);
 | ||||||
|  | +	litest_touch_move_to(dev, 0, 48, 48, 50, 50, 10, 1);
 | ||||||
|  | +	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
 | ||||||
|  | +
 | ||||||
|  | +	litest_button_click(dev, BTN_LEFT, true);
 | ||||||
|  | +	litest_drain_events(li);
 | ||||||
|  | +
 | ||||||
|  | +	litest_touch_move_to(dev, 0, 50, 50, 52, 52, 10, 1);
 | ||||||
|  | +	litest_touch_move_to(dev, 0, 52, 52, 48, 48, 10, 1);
 | ||||||
|  | +	litest_touch_move_to(dev, 0, 48, 48, 50, 50, 10, 1);
 | ||||||
|  | +
 | ||||||
|  | +	litest_assert_empty_queue(li);
 | ||||||
|  | +
 | ||||||
|  | +	litest_button_click(dev, BTN_LEFT, false);
 | ||||||
|  | +	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_BUTTON);
 | ||||||
|  | +
 | ||||||
|  | +	/* still pinned after release */
 | ||||||
|  | +	litest_touch_move_to(dev, 0, 50, 50, 52, 52, 10, 1);
 | ||||||
|  | +	litest_touch_move_to(dev, 0, 52, 52, 48, 48, 10, 1);
 | ||||||
|  | +	litest_touch_move_to(dev, 0, 48, 48, 50, 50, 10, 1);
 | ||||||
|  | +
 | ||||||
|  | +	litest_assert_empty_queue(li);
 | ||||||
|  | +
 | ||||||
|  | +	/* move to unpin */
 | ||||||
|  | +	litest_touch_move_to(dev, 0, 50, 50, 70, 70, 10, 1);
 | ||||||
|  | +	litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
 | ||||||
|  | +}
 | ||||||
|  | +END_TEST
 | ||||||
|  | +
 | ||||||
|  |  START_TEST(clickpad_softbutton_left) | ||||||
|  |  { | ||||||
|  |  	struct litest_device *dev = litest_current_device(); | ||||||
|  | @@ -5144,6 +5191,7 @@ litest_setup_tests(void)
 | ||||||
|  |  	litest_add("touchpad:click", touchpad_btn_left, LITEST_TOUCHPAD|LITEST_BUTTON, LITEST_CLICKPAD); | ||||||
|  |  	litest_add("touchpad:click", clickpad_btn_left, LITEST_CLICKPAD, LITEST_ANY); | ||||||
|  |  	litest_add("touchpad:click", clickpad_click_n_drag, LITEST_CLICKPAD, LITEST_SINGLE_TOUCH); | ||||||
|  | +	litest_add("touchpad:click", clickpad_finger_pin, LITEST_CLICKPAD, LITEST_ANY);
 | ||||||
|  |   | ||||||
|  |  	litest_add("touchpad:softbutton", clickpad_softbutton_left, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD); | ||||||
|  |  	litest_add("touchpad:softbutton", clickpad_softbutton_right, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD); | ||||||
|  | -- 
 | ||||||
|  | 2.4.3 | ||||||
|  | 
 | ||||||
| @ -5,7 +5,7 @@ | |||||||
| 
 | 
 | ||||||
| Name:           libinput | Name:           libinput | ||||||
| Version:        0.17.0 | Version:        0.17.0 | ||||||
| Release:        3%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist} | Release:        4%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist} | ||||||
| Summary:        Input device library | Summary:        Input device library | ||||||
| 
 | 
 | ||||||
| License:        MIT | License:        MIT | ||||||
| @ -19,6 +19,8 @@ Source0:        http://www.freedesktop.org/software/libinput/libinput-%{version} | |||||||
| %endif | %endif | ||||||
| 
 | 
 | ||||||
| Patch01:        0001-filter-require-minimum-acceleration-factor-of-0.3.patch | Patch01:        0001-filter-require-minimum-acceleration-factor-of-0.3.patch | ||||||
|  | Patch02:        0001-touchpad-fix-pinned-finger-drifting.patch | ||||||
|  | Patch03:        0001-touchpad-set-the-finger-pin-distance-to-5mm-where-po.patch | ||||||
| 
 | 
 | ||||||
| BuildRequires:  git | BuildRequires:  git | ||||||
| BuildRequires:  autoconf automake libtool pkgconfig | BuildRequires:  autoconf automake libtool pkgconfig | ||||||
| @ -96,6 +98,9 @@ find $RPM_BUILD_ROOT -name '*.la' -delete | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| %changelog | %changelog | ||||||
|  | * Tue Jun 16 2015 Peter Hutterer <peter.hutterer@redhat.com> 0.17.0-4 | ||||||
|  | - Avoid erroneous finger movement after a physical click (#1230441) | ||||||
|  | 
 | ||||||
| * Fri Jun 12 2015 Peter Hutterer <peter.hutterer@redhat.com> 0.17.0-3 | * Fri Jun 12 2015 Peter Hutterer <peter.hutterer@redhat.com> 0.17.0-3 | ||||||
| - Require udev.pc for the build | - Require udev.pc for the build | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user