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>
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);
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);
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);
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)
{
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)
{
struct motion_filter_interface accelerator_interface = {
accelerator_filter,
+ accelerator_restart,
accelerator_destroy,
accelerator_set_speed,
};
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);