[PATCH libinput 3/3] filter: enforce minimum velocity

Peter Hutterer peter.hutterer at who-t.net
Sun May 31 23:13:23 PDT 2015


In the current code, a timeout or direction change on the first tracker will
result in a velocity of 0. Really slow movements will thus always be zero, and
the first event after a direction is swallowed.

Enforce a minimum velocity:
In the case of a timeout, assume the current velocity is that of
distance/timeout. In the case of a direction change, the velocity is simply
that since the last tracker.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/filter.c    | 34 ++++++++++++++++++++++++++++++----
 test/touchpad.c | 10 +++++-----
 2 files changed, 35 insertions(+), 9 deletions(-)

diff --git a/src/filter.c b/src/filter.c
index 3845c7f..c54d866 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -144,6 +144,24 @@ calculate_tracker_velocity(struct pointer_tracker *tracker, uint64_t time)
 	return normalized_length(tracker->delta) / tdelta; /* units/ms */
 }
 
+static inline double
+calculate_velocity_after_timeout(struct pointer_tracker *tracker)
+{
+	/* First movement after timeout needs special handling.
+	 *
+	 * When we trigger the timeout, the last event is too far in the
+	 * past to use it for velocity calculation across multiple tracker
+	 * values.
+	 *
+	 * Use the motion timeout itself to calculate the speed rather than
+	 * the last tracker time. This errs on the side of being too fast
+	 * for really slow movements but provides much more useful initial
+	 * movement in normal use-cases (pause, move, pause, move)
+	 */
+	return calculate_tracker_velocity(tracker,
+					  tracker->time + MOTION_TIMEOUT);
+}
+
 static double
 calculate_velocity(struct pointer_accelerator *accel, uint64_t time)
 {
@@ -163,15 +181,23 @@ calculate_velocity(struct pointer_accelerator *accel, uint64_t time)
 
 		/* Stop if too far away in time */
 		if (time - tracker->time > MOTION_TIMEOUT ||
-		    tracker->time > time)
+		    tracker->time > time) {
+			if (offset == 1)
+				result = calculate_velocity_after_timeout(tracker);
 			break;
+		}
+
+		velocity = calculate_tracker_velocity(tracker, time);
 
 		/* Stop if direction changed */
 		dir &= tracker->dir;
-		if (dir == 0)
+		if (dir == 0) {
+			/* First movement after dirchange - velocity is that
+			 * of the last movement */
+			if (offset == 1)
+				result = velocity;
 			break;
-
-		velocity = calculate_tracker_velocity(tracker, time);
+		}
 
 		if (initial_velocity == 0.0) {
 			result = initial_velocity = velocity;
diff --git a/test/touchpad.c b/test/touchpad.c
index 5579c04..a747910 100644
--- a/test/touchpad.c
+++ b/test/touchpad.c
@@ -2959,7 +2959,7 @@ START_TEST(touchpad_edge_scroll)
 	litest_touch_up(dev, 0);
 
 	libinput_dispatch(li);
-	litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 10);
+	litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 4);
 	litest_assert_empty_queue(li);
 
 	litest_touch_down(dev, 0, 99, 80);
@@ -2967,7 +2967,7 @@ START_TEST(touchpad_edge_scroll)
 	litest_touch_up(dev, 0);
 
 	libinput_dispatch(li);
-	litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -10);
+	litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -4);
 	litest_assert_empty_queue(li);
 
 	litest_touch_down(dev, 0, 20, 99);
@@ -2975,7 +2975,7 @@ START_TEST(touchpad_edge_scroll)
 	litest_touch_up(dev, 0);
 
 	libinput_dispatch(li);
-	litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 10);
+	litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 4);
 	litest_assert_empty_queue(li);
 
 	litest_touch_down(dev, 0, 70, 99);
@@ -2983,7 +2983,7 @@ START_TEST(touchpad_edge_scroll)
 	litest_touch_up(dev, 0);
 
 	libinput_dispatch(li);
-	litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -10);
+	litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -4);
 	litest_assert_empty_queue(li);
 }
 END_TEST
@@ -3065,7 +3065,7 @@ START_TEST(touchpad_edge_scroll_no_motion)
 	litest_touch_up(dev, 0);
 	libinput_dispatch(li);
 
-	litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 5);
+	litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 4);
 	litest_assert_empty_queue(li);
 }
 END_TEST
-- 
2.4.1



More information about the wayland-devel mailing list