[PATCH libinput] touchpad: restart the motion filter on touch begin

Peter Hutterer peter.hutterer at who-t.net
Tue Jun 9 18:25:56 PDT 2015


Our motion filter takes the last couple of vectors to calculate speed,
provided the direction stays the same and it is within a certain timeout. It
does not take into account lifting the finger, so the velocity on the first
event is off.

Real-world impact is mainly on scrolling. Before commit 289e4675
	filter: enforce minimum velocity
the first motion on a scroll was accelerated by a factor of 0 and swallowed.
After 289e4675 the motion was calculated based on the timeout and a fraction
of the expected effect. Now the first scroll motion is based on the real
finger motion since setting the finger down and thus feels a bit more
responsive.

It also makes a couple of test cases using litest_assert_scroll() work again
since the miniumum motion is now as expected.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad.c |  7 +++++++
 src/filter-private.h    |  3 +++
 src/filter.c            | 31 +++++++++++++++++++++++++++++++
 src/filter.h            |  5 +++++
 4 files changed, 46 insertions(+)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 0154e89..8c28ff7 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -666,6 +666,7 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
 	struct tp_touch *t;
 	struct tp_touch *first = tp_get_touch(tp, 0);
 	unsigned int i;
+	bool restart_filter = false;
 
 	tp_process_fake_touches(tp, time);
 	tp_unhover_touches(tp, time);
@@ -692,8 +693,14 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
 		tp_motion_history_push(t);
 
 		tp_unpin_finger(tp, t);
+
+		if (t->state == TOUCH_BEGIN)
+			restart_filter = true;
 	}
 
+	if (restart_filter)
+		filter_restart(tp->device->pointer.filter, tp, time);
+
 	tp_button_handle_state(tp, time);
 	tp_edge_scroll_handle_state(tp, time);
 
diff --git a/src/filter-private.h b/src/filter-private.h
index 0e796f1..8a206d6 100644
--- a/src/filter-private.h
+++ b/src/filter-private.h
@@ -32,6 +32,9 @@ struct motion_filter_interface {
 			   struct motion_filter *filter,
 			   const struct normalized_coords *unaccelerated,
 			   void *data, uint64_t time);
+	void (*restart)(struct motion_filter *filter,
+			void *data,
+			uint64_t time);
 	void (*destroy)(struct motion_filter *filter);
 	bool (*set_speed)(struct motion_filter *filter,
 			  double speed);
diff --git a/src/filter.c b/src/filter.c
index ed5a184..ee4ce9e 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -44,6 +44,13 @@ filter_dispatch(struct motion_filter *filter,
 }
 
 void
+filter_restart(struct motion_filter *filter,
+	       void *data, uint64_t time)
+{
+	filter->interface->restart(filter, data, time);
+}
+
+void
 filter_destroy(struct motion_filter *filter)
 {
 	if (!filter)
@@ -274,6 +281,29 @@ accelerator_filter(struct motion_filter *filter,
 }
 
 static void
+accelerator_restart(struct motion_filter *filter,
+		    void *data,
+		    uint64_t time)
+{
+	struct pointer_accelerator *accel =
+		(struct pointer_accelerator *) filter;
+	unsigned int offset;
+	struct pointer_tracker *tracker;
+
+	for (offset = 1; offset < NUM_POINTER_TRACKERS; offset++) {
+		tracker = tracker_by_offset(accel, offset);
+		tracker->time = 0;
+		tracker->dir = 0;
+		tracker->delta.x = 0;
+		tracker->delta.y = 0;
+	}
+
+	tracker = tracker_by_offset(accel, 0);
+	tracker->time = time;
+	tracker->dir = UNDEFINED_DIRECTION;
+}
+
+static void
 accelerator_destroy(struct motion_filter *filter)
 {
 	struct pointer_accelerator *accel =
@@ -309,6 +339,7 @@ accelerator_set_speed(struct motion_filter *filter,
 
 struct motion_filter_interface accelerator_interface = {
 	accelerator_filter,
+	accelerator_restart,
 	accelerator_destroy,
 	accelerator_set_speed,
 };
diff --git a/src/filter.h b/src/filter.h
index 16896a4..03f510d 100644
--- a/src/filter.h
+++ b/src/filter.h
@@ -37,6 +37,11 @@ struct normalized_coords
 filter_dispatch(struct motion_filter *filter,
 		const struct normalized_coords *unaccelerated,
 		void *data, uint64_t time);
+
+void
+filter_restart(struct motion_filter *filter,
+	       void *data, uint64_t time);
+
 void
 filter_destroy(struct motion_filter *filter);
 
-- 
2.4.1



More information about the wayland-devel mailing list