From 289e4675c81d2fe32650295ce2b6a66a1ebb9f24 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 22 Apr 2015 12:25:13 +1000 Subject: [PATCH libinput 3/3] filter: enforce minimum velocity 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 Reviewed-by: Hans de Goede --- 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