From 105e725602791bd02ea800fd4298d3443c14ba58 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 10 Jun 2015 09:54:06 +1000 Subject: [PATCH] touchpad: restart the motion filter on touch begin 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 Reviewed-by: Hans de Goede --- 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 0154e895..8c28ff79 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 0e796f1a..8a206d69 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 c54d866c..6d9b9c34 100644 --- a/src/filter.c +++ b/src/filter.c @@ -43,6 +43,13 @@ filter_dispatch(struct motion_filter *filter, return filter->interface->filter(filter, unaccelerated, data, time); } +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) { @@ -273,6 +280,29 @@ accelerator_filter(struct motion_filter *filter, return accelerated; } +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) { @@ -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 16896a4c..03f510d0 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);