summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2021-03-11 14:45:17 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2021-03-11 16:33:00 +1000
commit42d6fed86864f97bde668fe5981b442d03e66815 (patch)
tree12e31af230b9ebf5fc1c0ee6a0b69f9fc0a76ae4
parent832c346b2befc0ae0d2a85bea233f144b635eecd (diff)
downloadlibinput-42d6fed86864f97bde668fe5981b442d03e66815.tar.gz
touchpad: always push a touch's current point to the motion history
The way touchpads (generally) work is that they get the position of each finger on each scanout. The kernel filters touches that haven't moved to reduce bandwidth so any touch that is logically down that we don't see an update for is in the same position as during the last scanout. Previously, touches that didn't sent events were effectively ignored, causing our jump detection to fail: - time t0: touch moves to position x/y, motion history time is set to t0 - time t1..t5: touch remains at position for several frames, no updates to the motion history - time t6: touch jumps to position x+a/y+b - tp_detect_jumps() sees the last update time is t0 which is too long ago and exits without detecting a jump This is fixed by pushing to the motion history any time we have *any* update - if the touchpad notices a state change on any touch update all touches with their current position, whether it changed or not. This obsoletes the `time` field in the tp_touch struct, most of this patch is passing down the current time to the few users of t->time. Fixes #578 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--src/evdev-mt-touchpad-buttons.c105
-rw-r--r--src/evdev-mt-touchpad-edge-scroll.c96
-rw-r--r--src/evdev-mt-touchpad.c30
-rw-r--r--src/evdev-mt-touchpad.h1
4 files changed, 141 insertions, 91 deletions
diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index 6ce35218..a6373a93 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -143,17 +143,21 @@ is_inside_top_middle_area(const struct tp_dispatch *tp,
}
static void
-tp_button_set_enter_timer(struct tp_dispatch *tp, struct tp_touch *t)
+tp_button_set_enter_timer(struct tp_dispatch *tp,
+ struct tp_touch *t,
+ uint64_t time)
{
libinput_timer_set(&t->button.timer,
- t->time + DEFAULT_BUTTON_ENTER_TIMEOUT);
+ time + DEFAULT_BUTTON_ENTER_TIMEOUT);
}
static void
-tp_button_set_leave_timer(struct tp_dispatch *tp, struct tp_touch *t)
+tp_button_set_leave_timer(struct tp_dispatch *tp,
+ struct tp_touch *t,
+ uint64_t time)
{
libinput_timer_set(&t->button.timer,
- t->time + DEFAULT_BUTTON_LEAVE_TIMEOUT);
+ time + DEFAULT_BUTTON_LEAVE_TIMEOUT);
}
/*
@@ -164,7 +168,8 @@ static void
tp_button_set_state(struct tp_dispatch *tp,
struct tp_touch *t,
enum button_state new_state,
- enum button_event event)
+ enum button_event event,
+ uint64_t time)
{
libinput_timer_cancel(&t->button.timer);
@@ -184,10 +189,10 @@ tp_button_set_state(struct tp_dispatch *tp,
break;
case BUTTON_STATE_TOP_NEW:
t->button.current = event;
- tp_button_set_enter_timer(tp, t);
+ tp_button_set_enter_timer(tp, t, time);
break;
case BUTTON_STATE_TOP_TO_IGNORE:
- tp_button_set_leave_timer(tp, t);
+ tp_button_set_leave_timer(tp, t, time);
break;
case BUTTON_STATE_IGNORE:
t->button.current = 0;
@@ -198,24 +203,25 @@ tp_button_set_state(struct tp_dispatch *tp,
static void
tp_button_none_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
- enum button_event event)
+ enum button_event event,
+ uint64_t time)
{
switch (event) {
case BUTTON_EVENT_IN_BOTTOM_R:
case BUTTON_EVENT_IN_BOTTOM_M:
case BUTTON_EVENT_IN_BOTTOM_L:
- tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_BOTTOM, event, time);
break;
case BUTTON_EVENT_IN_TOP_R:
case BUTTON_EVENT_IN_TOP_M:
case BUTTON_EVENT_IN_TOP_L:
- tp_button_set_state(tp, t, BUTTON_STATE_TOP_NEW, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_TOP_NEW, event, time);
break;
case BUTTON_EVENT_IN_AREA:
- tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_AREA, event, time);
break;
case BUTTON_EVENT_UP:
- tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
break;
case BUTTON_EVENT_PRESS:
case BUTTON_EVENT_RELEASE:
@@ -227,7 +233,8 @@ tp_button_none_handle_event(struct tp_dispatch *tp,
static void
tp_button_area_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
- enum button_event event)
+ enum button_event event,
+ uint64_t time)
{
switch (event) {
case BUTTON_EVENT_IN_BOTTOM_R:
@@ -239,7 +246,7 @@ tp_button_area_handle_event(struct tp_dispatch *tp,
case BUTTON_EVENT_IN_AREA:
break;
case BUTTON_EVENT_UP:
- tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
break;
case BUTTON_EVENT_PRESS:
case BUTTON_EVENT_RELEASE:
@@ -281,7 +288,8 @@ tp_button_release_other_bottom_touches(struct tp_dispatch *tp,
static void
tp_button_bottom_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
- enum button_event event)
+ enum button_event event,
+ uint64_t time)
{
switch (event) {
case BUTTON_EVENT_IN_BOTTOM_R:
@@ -291,13 +299,14 @@ tp_button_bottom_handle_event(struct tp_dispatch *tp,
tp_button_set_state(tp,
t,
BUTTON_STATE_BOTTOM,
- event);
+ event,
+ time);
break;
case BUTTON_EVENT_IN_TOP_R:
case BUTTON_EVENT_IN_TOP_M:
case BUTTON_EVENT_IN_TOP_L:
case BUTTON_EVENT_IN_AREA:
- tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_AREA, event, time);
/* We just transitioned one finger from BOTTOM to AREA,
* if there are other fingers in BOTTOM that started
@@ -308,7 +317,7 @@ tp_button_bottom_handle_event(struct tp_dispatch *tp,
t->button.initial_time);
break;
case BUTTON_EVENT_UP:
- tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
break;
case BUTTON_EVENT_PRESS:
case BUTTON_EVENT_RELEASE:
@@ -320,13 +329,14 @@ tp_button_bottom_handle_event(struct tp_dispatch *tp,
static void
tp_button_top_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
- enum button_event event)
+ enum button_event event,
+ uint64_t time)
{
switch (event) {
case BUTTON_EVENT_IN_BOTTOM_R:
case BUTTON_EVENT_IN_BOTTOM_M:
case BUTTON_EVENT_IN_BOTTOM_L:
- tp_button_set_state(tp, t, BUTTON_STATE_TOP_TO_IGNORE, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_TOP_TO_IGNORE, event, time);
break;
case BUTTON_EVENT_IN_TOP_R:
case BUTTON_EVENT_IN_TOP_M:
@@ -335,13 +345,14 @@ tp_button_top_handle_event(struct tp_dispatch *tp,
tp_button_set_state(tp,
t,
BUTTON_STATE_TOP_NEW,
- event);
+ event,
+ time);
break;
case BUTTON_EVENT_IN_AREA:
- tp_button_set_state(tp, t, BUTTON_STATE_TOP_TO_IGNORE, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_TOP_TO_IGNORE, event, time);
break;
case BUTTON_EVENT_UP:
- tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
break;
case BUTTON_EVENT_PRESS:
case BUTTON_EVENT_RELEASE:
@@ -353,13 +364,14 @@ tp_button_top_handle_event(struct tp_dispatch *tp,
static void
tp_button_top_new_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
- enum button_event event)
+ enum button_event event,
+ uint64_t time)
{
switch(event) {
case BUTTON_EVENT_IN_BOTTOM_R:
case BUTTON_EVENT_IN_BOTTOM_M:
case BUTTON_EVENT_IN_BOTTOM_L:
- tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_AREA, event, time);
break;
case BUTTON_EVENT_IN_TOP_R:
case BUTTON_EVENT_IN_TOP_M:
@@ -368,21 +380,22 @@ tp_button_top_new_handle_event(struct tp_dispatch *tp,
tp_button_set_state(tp,
t,
BUTTON_STATE_TOP_NEW,
- event);
+ event,
+ time);
break;
case BUTTON_EVENT_IN_AREA:
- tp_button_set_state(tp, t, BUTTON_STATE_AREA, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_AREA, event, time);
break;
case BUTTON_EVENT_UP:
- tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
break;
case BUTTON_EVENT_PRESS:
- tp_button_set_state(tp, t, BUTTON_STATE_TOP, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_TOP, event, time);
break;
case BUTTON_EVENT_RELEASE:
break;
case BUTTON_EVENT_TIMEOUT:
- tp_button_set_state(tp, t, BUTTON_STATE_TOP, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_TOP, event, time);
break;
}
}
@@ -390,7 +403,8 @@ tp_button_top_new_handle_event(struct tp_dispatch *tp,
static void
tp_button_top_to_ignore_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
- enum button_event event)
+ enum button_event event,
+ uint64_t time)
{
switch(event) {
case BUTTON_EVENT_IN_TOP_R:
@@ -400,12 +414,14 @@ tp_button_top_to_ignore_handle_event(struct tp_dispatch *tp,
tp_button_set_state(tp,
t,
BUTTON_STATE_TOP,
- event);
+ event,
+ time);
else
tp_button_set_state(tp,
t,
BUTTON_STATE_TOP_NEW,
- event);
+ event,
+ time);
break;
case BUTTON_EVENT_IN_BOTTOM_R:
case BUTTON_EVENT_IN_BOTTOM_M:
@@ -413,13 +429,13 @@ tp_button_top_to_ignore_handle_event(struct tp_dispatch *tp,
case BUTTON_EVENT_IN_AREA:
break;
case BUTTON_EVENT_UP:
- tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
break;
case BUTTON_EVENT_PRESS:
case BUTTON_EVENT_RELEASE:
break;
case BUTTON_EVENT_TIMEOUT:
- tp_button_set_state(tp, t, BUTTON_STATE_IGNORE, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_IGNORE, event, time);
break;
}
}
@@ -427,7 +443,8 @@ tp_button_top_to_ignore_handle_event(struct tp_dispatch *tp,
static void
tp_button_ignore_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
- enum button_event event)
+ enum button_event event,
+ uint64_t time)
{
switch (event) {
case BUTTON_EVENT_IN_BOTTOM_R:
@@ -439,7 +456,7 @@ tp_button_ignore_handle_event(struct tp_dispatch *tp,
case BUTTON_EVENT_IN_AREA:
break;
case BUTTON_EVENT_UP:
- tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
+ tp_button_set_state(tp, t, BUTTON_STATE_NONE, event, time);
break;
case BUTTON_EVENT_PRESS:
t->button.current = BUTTON_EVENT_IN_AREA;
@@ -461,25 +478,25 @@ tp_button_handle_event(struct tp_dispatch *tp,
switch(t->button.state) {
case BUTTON_STATE_NONE:
- tp_button_none_handle_event(tp, t, event);
+ tp_button_none_handle_event(tp, t, event, time);
break;
case BUTTON_STATE_AREA:
- tp_button_area_handle_event(tp, t, event);
+ tp_button_area_handle_event(tp, t, event, time);
break;
case BUTTON_STATE_BOTTOM:
- tp_button_bottom_handle_event(tp, t, event);
+ tp_button_bottom_handle_event(tp, t, event, time);
break;
case BUTTON_STATE_TOP:
- tp_button_top_handle_event(tp, t, event);
+ tp_button_top_handle_event(tp, t, event, time);
break;
case BUTTON_STATE_TOP_NEW:
- tp_button_top_new_handle_event(tp, t, event);
+ tp_button_top_new_handle_event(tp, t, event, time);
break;
case BUTTON_STATE_TOP_TO_IGNORE:
- tp_button_top_to_ignore_handle_event(tp, t, event);
+ tp_button_top_to_ignore_handle_event(tp, t, event, time);
break;
case BUTTON_STATE_IGNORE:
- tp_button_ignore_handle_event(tp, t, event);
+ tp_button_ignore_handle_event(tp, t, event, time);
break;
}
diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c
index 2cdec4cc..c17d7f59 100644
--- a/src/evdev-mt-touchpad-edge-scroll.c
+++ b/src/evdev-mt-touchpad-edge-scroll.c
@@ -88,7 +88,8 @@ tp_touch_get_edge(const struct tp_dispatch *tp, const struct tp_touch *t)
static inline void
tp_edge_scroll_set_timer(struct tp_dispatch *tp,
- struct tp_touch *t)
+ struct tp_touch *t,
+ uint64_t time)
{
const int DEFAULT_SCROLL_LOCK_TIMEOUT = ms2us(300);
/* if we use software buttons, we disable timeout-based
@@ -100,13 +101,14 @@ tp_edge_scroll_set_timer(struct tp_dispatch *tp,
return;
libinput_timer_set(&t->scroll.timer,
- t->time + DEFAULT_SCROLL_LOCK_TIMEOUT);
+ time + DEFAULT_SCROLL_LOCK_TIMEOUT);
}
static void
tp_edge_scroll_set_state(struct tp_dispatch *tp,
struct tp_touch *t,
- enum tp_edge_scroll_touch_state state)
+ enum tp_edge_scroll_touch_state state,
+ uint64_t time)
{
libinput_timer_cancel(&t->scroll.timer);
@@ -119,7 +121,7 @@ tp_edge_scroll_set_state(struct tp_dispatch *tp,
case EDGE_SCROLL_TOUCH_STATE_EDGE_NEW:
t->scroll.edge = tp_touch_get_edge(tp, t);
t->scroll.initial = t->point;
- tp_edge_scroll_set_timer(tp, t);
+ tp_edge_scroll_set_timer(tp, t, time);
break;
case EDGE_SCROLL_TOUCH_STATE_EDGE:
break;
@@ -132,16 +134,21 @@ tp_edge_scroll_set_state(struct tp_dispatch *tp,
static void
tp_edge_scroll_handle_none(struct tp_dispatch *tp,
struct tp_touch *t,
- enum scroll_event event)
+ enum scroll_event event,
+ uint64_t time)
{
switch (event) {
case SCROLL_EVENT_TOUCH:
if (tp_touch_get_edge(tp, t)) {
- tp_edge_scroll_set_state(tp, t,
- EDGE_SCROLL_TOUCH_STATE_EDGE_NEW);
+ tp_edge_scroll_set_state(tp,
+ t,
+ EDGE_SCROLL_TOUCH_STATE_EDGE_NEW,
+ time);
} else {
- tp_edge_scroll_set_state(tp, t,
- EDGE_SCROLL_TOUCH_STATE_AREA);
+ tp_edge_scroll_set_state(tp,
+ t,
+ EDGE_SCROLL_TOUCH_STATE_AREA,
+ time);
}
break;
case SCROLL_EVENT_MOTION:
@@ -159,7 +166,8 @@ tp_edge_scroll_handle_none(struct tp_dispatch *tp,
static void
tp_edge_scroll_handle_edge_new(struct tp_dispatch *tp,
struct tp_touch *t,
- enum scroll_event event)
+ enum scroll_event event,
+ uint64_t time)
{
switch (event) {
case SCROLL_EVENT_TOUCH:
@@ -171,15 +179,23 @@ tp_edge_scroll_handle_edge_new(struct tp_dispatch *tp,
case SCROLL_EVENT_MOTION:
t->scroll.edge &= tp_touch_get_edge(tp, t);
if (!t->scroll.edge)
- tp_edge_scroll_set_state(tp, t,
- EDGE_SCROLL_TOUCH_STATE_AREA);
+ tp_edge_scroll_set_state(tp,
+ t,
+ EDGE_SCROLL_TOUCH_STATE_AREA,
+ time);
break;
case SCROLL_EVENT_RELEASE:
- tp_edge_scroll_set_state(tp, t, EDGE_SCROLL_TOUCH_STATE_NONE);
+ tp_edge_scroll_set_state(tp,
+ t,
+ EDGE_SCROLL_TOUCH_STATE_NONE,
+ time);
break;
case SCROLL_EVENT_TIMEOUT:
case SCROLL_EVENT_POSTED:
- tp_edge_scroll_set_state(tp, t, EDGE_SCROLL_TOUCH_STATE_EDGE);
+ tp_edge_scroll_set_state(tp,
+ t,
+ EDGE_SCROLL_TOUCH_STATE_EDGE,
+ time);
break;
}
}
@@ -187,7 +203,8 @@ tp_edge_scroll_handle_edge_new(struct tp_dispatch *tp,
static void
tp_edge_scroll_handle_edge(struct tp_dispatch *tp,
struct tp_touch *t,
- enum scroll_event event)
+ enum scroll_event event,
+ uint64_t time)
{
switch (event) {
case SCROLL_EVENT_TOUCH:
@@ -202,12 +219,17 @@ tp_edge_scroll_handle_edge(struct tp_dispatch *tp,
if (t->scroll.edge == (EDGE_RIGHT | EDGE_BOTTOM)) {
t->scroll.edge &= tp_touch_get_edge(tp, t);
if (!t->scroll.edge)
- tp_edge_scroll_set_state(tp, t,
- EDGE_SCROLL_TOUCH_STATE_AREA);
+ tp_edge_scroll_set_state(tp,
+ t,
+ EDGE_SCROLL_TOUCH_STATE_AREA,
+ time);
}
break;
case SCROLL_EVENT_RELEASE:
- tp_edge_scroll_set_state(tp, t, EDGE_SCROLL_TOUCH_STATE_NONE);
+ tp_edge_scroll_set_state(tp,
+ t,
+ EDGE_SCROLL_TOUCH_STATE_NONE,
+ time);
break;
case SCROLL_EVENT_POSTED:
break;
@@ -217,7 +239,8 @@ tp_edge_scroll_handle_edge(struct tp_dispatch *tp,
static void
tp_edge_scroll_handle_area(struct tp_dispatch *tp,
struct tp_touch *t,
- enum scroll_event event)
+ enum scroll_event event,
+ uint64_t time)
{
switch (event) {
case SCROLL_EVENT_TOUCH:
@@ -230,7 +253,10 @@ tp_edge_scroll_handle_area(struct tp_dispatch *tp,
case SCROLL_EVENT_MOTION:
break;
case SCROLL_EVENT_RELEASE:
- tp_edge_scroll_set_state(tp, t, EDGE_SCROLL_TOUCH_STATE_NONE);
+ tp_edge_scroll_set_state(tp,
+ t,
+ EDGE_SCROLL_TOUCH_STATE_NONE,
+ time);
break;
}
}
@@ -238,22 +264,23 @@ tp_edge_scroll_handle_area(struct tp_dispatch *tp,
static void
tp_edge_scroll_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
- enum scroll_event event)
+ enum scroll_event event,
+ uint64_t time)
{
enum tp_edge_scroll_touch_state current = t->scroll.edge_state;
switch (current) {
case EDGE_SCROLL_TOUCH_STATE_NONE:
- tp_edge_scroll_handle_none(tp, t, event);
+ tp_edge_scroll_handle_none(tp, t, event, time);
break;
case EDGE_SCROLL_TOUCH_STATE_EDGE_NEW:
- tp_edge_scroll_handle_edge_new(tp, t, event);
+ tp_edge_scroll_handle_edge_new(tp, t, event, time);
break;
case EDGE_SCROLL_TOUCH_STATE_EDGE:
- tp_edge_scroll_handle_edge(tp, t, event);
+ tp_edge_scroll_handle_edge(tp, t, event, time);
break;
case EDGE_SCROLL_TOUCH_STATE_AREA:
- tp_edge_scroll_handle_area(tp, t, event);
+ tp_edge_scroll_handle_area(tp, t, event, time);
break;
}
@@ -271,7 +298,7 @@ tp_edge_scroll_handle_timeout(uint64_t now, void *data)
{
struct tp_touch *t = data;
- tp_edge_scroll_handle_event(t->tp, t, SCROLL_EVENT_TIMEOUT);
+ tp_edge_scroll_handle_event(t->tp, t, SCROLL_EVENT_TIMEOUT, now);
}
void
@@ -359,10 +386,16 @@ tp_edge_scroll_handle_state(struct tp_dispatch *tp, uint64_t time)
case TOUCH_HOVERING:
break;
case TOUCH_BEGIN:
- tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_TOUCH);
+ tp_edge_scroll_handle_event(tp,
+ t,
+ SCROLL_EVENT_TOUCH,
+ time);
break;
case TOUCH_UPDATE:
- tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_MOTION);
+ tp_edge_scroll_handle_event(tp,
+ t,
+ SCROLL_EVENT_MOTION,
+ time);
break;
case TOUCH_MAYBE_END:
/* This shouldn't happen we transfer to TOUCH_END
@@ -373,7 +406,10 @@ tp_edge_scroll_handle_state(struct tp_dispatch *tp, uint64_t time)
t->state);
/* fallthrough */
case TOUCH_END:
- tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_RELEASE);
+ tp_edge_scroll_handle_event(tp,
+ t,
+ SCROLL_EVENT_RELEASE,
+ time);
break;
}
}
@@ -465,7 +501,7 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
&zero_discrete);
t->scroll.direction = axis;
- tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_POSTED);
+ tp_edge_scroll_handle_event(tp, t, SCROLL_EVENT_POSTED, time);
}
return 0; /* Edge touches are suppressed by edge_scroll_touch_active */
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 24dc4e45..28c21d8e 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -94,7 +94,9 @@ tp_filter_motion_unaccelerated(struct tp_dispatch *tp,
}
static inline void
-tp_calculate_motion_speed(struct tp_dispatch *tp, struct tp_touch *t)
+tp_calculate_motion_speed(struct tp_dispatch *tp,
+ struct tp_touch *t,
+ uint64_t time)
{
const struct tp_history_point *last;
struct device_coords delta;
@@ -129,14 +131,14 @@ tp_calculate_motion_speed(struct tp_dispatch *tp, struct tp_touch *t)
mm = evdev_device_unit_delta_to_mm(tp->device, &delta);
distance = length_in_mm(mm);
- speed = distance/(t->time - last->time); /* mm/us */
+ speed = distance/(time - last->time); /* mm/us */
speed *= 1000000; /* mm/s */
t->speed.last_speed = speed;
}
static inline void
-tp_motion_history_push(struct tp_touch *t)
+tp_motion_history_push(struct tp_touch *t, uint64_t time)
{
int motion_index = (t->history.index + 1) % TOUCHPAD_HISTORY_LENGTH;
@@ -144,7 +146,7 @@ tp_motion_history_push(struct tp_touch *t)
t->history.count++;
t->history.samples[motion_index].point = t->point;
- t->history.samples[motion_index].time = t->time;
+ t->history.samples[motion_index].time = time;
t->history.index = motion_index;
}
@@ -338,7 +340,6 @@ tp_new_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
t->palm.state = PALM_NONE;
t->state = TOUCH_HOVERING;
t->pinned.is_pinned = false;
- t->time = time;
t->speed.last_speed = 0;
t->speed.exceeded_count = 0;
t->hysteresis.x_motion_history = 0;
@@ -350,7 +351,6 @@ tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
{
t->dirty = true;
t->state = TOUCH_BEGIN;
- t->time = time;
t->initial_time = time;
t->was_down = true;
tp->nfingers_down++;
@@ -433,7 +433,6 @@ tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
t->palm.state = PALM_NONE;
t->state = TOUCH_END;
t->pinned.is_pinned = false;
- t->time = time;
t->palm.time = 0;
t->speed.exceeded_count = 0;
tp->queued |= TOUCHPAD_EVENT_MOTION;
@@ -510,7 +509,6 @@ tp_process_absolute(struct tp_dispatch *tp,
e->code,
e->value);
t->point.x = rotated(tp, e->code, e->value);
- t->time = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_MOTION;
break;
@@ -519,7 +517,6 @@ tp_process_absolute(struct tp_dispatch *tp,
e->code,
e->value);
t->point.y = rotated(tp, e->code, e->value);
- t->time = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_MOTION;
break;
@@ -538,13 +535,11 @@ tp_process_absolute(struct tp_dispatch *tp,
break;
case ABS_MT_PRESSURE:
t->pressure = e->value;
- t->time = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_OTHERAXIS;
break;
case ABS_MT_TOOL_TYPE:
t->is_tool_palm = e->value == MT_TOOL_PALM;
- t->time = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_OTHERAXIS;
break;
@@ -574,7 +569,6 @@ tp_process_absolute_st(struct tp_dispatch *tp,
e->code,
e->value);
t->point.x = rotated(tp, e->code, e->value);
- t->time = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_MOTION;
break;
@@ -583,13 +577,11 @@ tp_process_absolute_st(struct tp_dispatch *tp,
e->code,
e->value);
t->point.y = rotated(tp, e->code, e->value);
- t->time = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_MOTION;
break;
case ABS_PRESSURE:
t->pressure = e->value;
- t->time = time;
t->dirty = true;
tp->queued |= TOUCHPAD_EVENT_OTHERAXIS;
break;
@@ -1746,6 +1738,12 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
speed_exceeded_count = max(speed_exceeded_count,
t->speed.exceeded_count);
+
+ /* A touch that hasn't moved must be in the same
+ * position, so let's add this to the motion
+ * history.
+ */
+ tp_motion_history_push(t, time);
continue;
}
@@ -1763,7 +1761,7 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
tp_palm_detect(tp, t, time);
tp_detect_wobbling(tp, t, time);
tp_motion_hysteresis(tp, t);
- tp_motion_history_push(t);
+ tp_motion_history_push(t, time);
/* Touch speed handling: if we'are above the threshold,
* count each event that we're over the threshold up to 10
@@ -1787,7 +1785,7 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
speed_exceeded_count = max(speed_exceeded_count,
t->speed.exceeded_count);
- tp_calculate_motion_speed(tp, t);
+ tp_calculate_motion_speed(tp, t, time);
tp_unpin_finger(tp, t);
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 6e1e1e3a..abd05114 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -185,7 +185,6 @@ struct tp_touch {
bool has_ended; /* TRACKING_ID == -1 */
bool dirty;
struct device_coords point;
- uint64_t time;
uint64_t initial_time;
int pressure;
bool is_tool_palm; /* MT_TOOL_PALM */