[PATCH libinput 4/4] touchpad: reset the motion history during/after a slots->nfake crossover
Peter Hutterer
peter.hutterer at who-t.net
Mon Jul 20 22:51:04 PDT 2015
Whenever we cross from N slots to at least one fake finger, reset the motion
history and skip the next event too. Especially on serial Synaptics touchpads,
the first touch update after a two-slot → TRIPLETAP is garbage, as is the one
from TRIPLETAP → two slots.
Example sequence reproduce on a T440s:
E: 4.488757 0003 003a 0084 # EV_ABS / ABS_MT_PRESSURE 84
E: 4.488757 0003 002f 0001 # EV_ABS / ABS_MT_SLOT 1
E: 4.488757 0003 0039 0433 # EV_ABS / ABS_MT_TRACKING_ID 433
E: 4.488757 0003 0035 2500 # EV_ABS / ABS_MT_POSITION_X 2500
E: 4.488757 0003 0036 3064 # EV_ABS / ABS_MT_POSITION_Y 3064
E: 4.488757 0003 003a 0060 # EV_ABS / ABS_MT_PRESSURE 60
E: 4.488757 0003 0018 0084 # EV_ABS / ABS_PRESSURE 84
E: 4.488757 0001 0145 0000 # EV_KEY / BTN_TOOL_FINGER 0
E: 4.488757 0001 014e 0001 # EV_KEY / BTN_TOOL_TRIPLETAP 1
E: 4.488757 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
E: 4.508506 0003 002f 0000 # EV_ABS / ABS_MT_SLOT 0
E: 4.508506 0003 0036 2982 # EV_ABS / ABS_MT_POSITION_Y 2982
E: 4.508506 0003 003a 0086 # EV_ABS / ABS_MT_PRESSURE 86
E: 4.508506 0003 002f 0001 # EV_ABS / ABS_MT_SLOT 1
E: 4.508506 0003 0035 3464 # EV_ABS / ABS_MT_POSITION_X 3464
E: 4.508506 0003 0036 2716 # EV_ABS / ABS_MT_POSITION_Y 2716
E: 4.508506 0003 0001 2982 # EV_ABS / ABS_Y 2982
E: 4.508506 0003 0018 0086 # EV_ABS / ABS_PRESSURE 86
E: 4.508506 0000 0000 0000 # ------------ SYN_REPORT (0) ----------
subsequent events then hover around the 3464 mark, but that initial jump is
enough to cause a massive cursor jump.
https://bugs.freedesktop.org/show_bug.cgi?id=91352
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
src/evdev-mt-touchpad.c | 29 +++++++++++++++++++++++++++--
src/evdev-mt-touchpad.h | 9 +++++++++
2 files changed, 36 insertions(+), 2 deletions(-)
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 1bf206d..05a9b0f 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -760,6 +760,24 @@ tp_unhover_touches(struct tp_dispatch *tp, uint64_t time)
}
+static inline bool
+tp_need_motion_history_reset(struct tp_dispatch *tp)
+{
+ /* semi-mt finger postions may "jump" when nfingers changes */
+ if (tp->semi_mt && tp->nfingers_down != tp->old_nfingers_down)
+ return true;
+
+ /* if we're transitioning between slots and fake touches in either
+ * direction, we may get a coordinate jump
+ */
+ if (tp->nfingers_down != tp->old_nfingers_down &&
+ (tp->nfingers_down > tp->num_slots ||
+ tp->old_nfingers_down > tp->num_slots))
+ return true;
+
+ return false;
+}
+
static void
tp_process_state(struct tp_dispatch *tp, uint64_t time)
{
@@ -767,16 +785,23 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
struct tp_touch *first = tp_get_touch(tp, 0);
unsigned int i;
bool restart_filter = false;
+ bool want_motion_reset;
tp_process_fake_touches(tp, time);
tp_unhover_touches(tp, time);
+ want_motion_reset = tp_need_motion_history_reset(tp);
+
for (i = 0; i < tp->ntouches; i++) {
t = tp_get_touch(tp, i);
- /* semi-mt finger postions may "jump" when nfingers changes */
- if (tp->semi_mt && tp->nfingers_down != tp->old_nfingers_down)
+ if (want_motion_reset) {
tp_motion_history_reset(t);
+ t->quirks.reset_motion_history = true;
+ } else if (t->quirks.reset_motion_history) {
+ tp_motion_history_reset(t);
+ t->quirks.reset_motion_history = false;
+ }
if (i >= tp->num_slots && t->state != TOUCH_NONE) {
t->point = first->point;
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 61c4166..fc6d38e 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -148,6 +148,15 @@ struct tp_touch {
int pressure;
struct {
+ /* A quirk mostly used on Synaptics touchpads. In a
+ transition to/from fake touches > num_slots, the current
+ event data is likely garbage and the subsequent event
+ is likely too. This marker tells us to reset the motion
+ history again -> this effectively swallows any motion */
+ bool reset_motion_history;
+ } quirks;
+
+ struct {
struct device_coords samples[TOUCHPAD_HISTORY_LENGTH];
unsigned int index;
unsigned int count;
--
2.4.3
More information about the wayland-devel
mailing list