[PATCH 2/2 libinput] touchpad: add wobbling detection
Konstantin Kharlamov
Hi-Angel at yandex.ru
Sun Feb 18 10:09:24 UTC 2018
The details are explained in comment in the code. That aside, I shall
mention the check is so light, that it shouldn't influence CPU
performance even a bit, and can blindly be kept always enabled.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=104828
Signed-off-by: Konstantin Kharlamov <Hi-Angel at yandex.ru>
---
src/evdev-mt-touchpad.c | 33 +++++++++++++++++++++++++++++++++
src/evdev-mt-touchpad.h | 1 +
2 files changed, 34 insertions(+)
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index ead76456..e9f8ea4e 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -131,6 +131,37 @@ tp_motion_history_push(struct tp_touch *t)
t->history.index = motion_index;
}
+static inline void
+tp_does_wobble(struct tp_dispatch *tp, int x, uint64_t time)
+{
+ if (tp->hysteresis.enabled)
+ return;
+
+ /* Idea: if we got a tuple of *very* quick moves like {Left, Right, Left}, or
+ * {Right, Left, Right}, it means touchpad jitters since no human supposed to
+ * be able to move like that within thresholds
+ *
+ * Algo: we encode left moves as zeroes, and right as ones. We also drop the
+ * array to all zeroes when contraints are not satisfied. Then we search for
+ * the pattern {1,0,1}. It can't match {Left, Right, Left}, but it does match
+ * {Left, Right, Left, Right}, so it's okay.
+ */
+ if (time - tp->hysteresis.last_motion_time > ms2us(20) || x == 0) {
+ tp->hysteresis.x_motion_in_threshold = 0;
+ return;
+ }
+ tp->hysteresis.x_motion_in_threshold <<= 1;
+ if (x > 0) { // right move
+ tp->hysteresis.x_motion_in_threshold |= 1;
+ static const char r_l_r = 5; // {Right, Left, Right}
+ if (tp->hysteresis.x_motion_in_threshold & r_l_r) {
+ tp->hysteresis.enabled = true;
+ evdev_log_debug(tp->device, "hysteresis enabled\n");
+
+ }
+ }
+}
+
static inline void
tp_motion_hysteresis(struct tp_dispatch *tp,
struct tp_touch *t)
@@ -1405,6 +1436,7 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
tp_thumb_detect(tp, t, time);
tp_palm_detect(tp, t, time);
+ tp_does_wobble(tp, t->point.x, time);
tp_motion_hysteresis(tp, t);
tp_motion_history_push(t);
@@ -2918,6 +2950,7 @@ tp_init_hysteresis(struct tp_dispatch *tp)
tp->hysteresis.margin.x = res_x/2;
tp->hysteresis.margin.y = res_y/2;
tp->hysteresis.enabled = false;
+ tp->hysteresis.x_motion_in_threshold = 0;
}
static void
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 442f34a3..b738a592 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -276,6 +276,7 @@ struct tp_dispatch {
struct device_coords margin;
unsigned int other_event_count;
uint64_t last_motion_time;
+ char x_motion_in_threshold;
} hysteresis;
struct {
--
2.15.1
More information about the wayland-devel
mailing list