touchpad: restart the motion filter on touch begin
authorPeter Hutterer <peter.hutterer@who-t.net>
Tue, 9 Jun 2015 23:54:06 +0000 (09:54 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Wed, 10 Jun 2015 21:19:25 +0000 (07:19 +1000)
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@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
src/evdev-mt-touchpad.c
src/filter-private.h
src/filter.c
src/filter.h

index 0154e895c502fe2e60f6ce522893766ec8d816cb..8c28ff79a79bb867e70c719522c920726ea430cd 100644 (file)
@@ -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);
 
index 0e796f1a5e08a15ead0dff0a1b52b42a86299a16..8a206d69a9cafdc6337fcdeebfe338020a30f1e3 100644 (file)
@@ -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);
index c54d866c6f7abea7662ba71ddb04ac094da27a22..6d9b9c340013bf504f92dcd27ac2c4e2876bdb79 100644 (file)
@@ -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,
 };
index 16896a4cbc5714e15bbffb619797b4a88703d49c..03f510d0bb7d3190d0abc85c2a0b66324fe96b1c 100644 (file)
@@ -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);