2014-03-28 10:48 GMT+06:00 Peter Hutterer <peter.hutte...@who-t.net>:

> having said that, I'm currently struggling with getting libinput up to
> feature parity with the xorg drivers, hacking around broken devices will
> have to wait a bit, sorry.

No problem, I just did that for you. See the attached patch. Seems to
work here, but I am not 100% sure, especially about the non-mt case.
It does prevent sudden pointer jumps to the bottom left corner of the
screen (survived a while round of the Harvest Honors game, something
that the original driver cound not do!), but I also get some click
attempts mistreated as right-clicks. Probably because there are in
fact some moments when the touchpad thinks that two fingers are on it.

-- 
Alexander E. Patrakov
From e277805a6814c852e6a0a274b0bec7db93585e65 Mon Sep 17 00:00:00 2001
From: "Alexander E. Patrakov" <patra...@gmail.com>
Date: Fri, 28 Mar 2014 23:57:56 +0600
Subject: [PATCH] Detect and discard huge coordinate jumps on touchpads.

Such jumps are usually consequences of the touchpad firmware
failing to notice that a different finger is in fact touching the
touchpad. If not discarded, such events lead to sudden pointer
jumps into screen corners.

BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=76722
Signed-off-by: Alexander E. Patrakov <patra...@gmail.com>
---
 src/evdev-mt-touchpad.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/evdev-mt-touchpad.h |  3 +++
 2 files changed, 51 insertions(+)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index bbbd8f3..feddced 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -32,6 +32,7 @@
 #define DEFAULT_MIN_ACCEL_FACTOR 0.16
 #define DEFAULT_MAX_ACCEL_FACTOR 1.0
 #define DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR 700.0
+#define DEFAULT_JUMP_DETECTION_DENOMINATOR 8.0
 
 static inline int
 tp_hysteresis(int in, int center, int margin)
@@ -187,6 +188,48 @@ tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t)
 	tp->queued |= TOUCHPAD_EVENT_MOTION;
 }
 
+static inline void
+tp_disrupt_touch(struct tp_dispatch *tp, struct tp_touch *t)
+{
+	if (t->state == TOUCH_NONE)
+		return;
+
+	tp_end_touch(tp, t);
+	t->state = TOUCH_DISRUPT;
+}
+
+static inline void
+tp_undisrupt_touch(struct tp_dispatch *tp, struct tp_touch *t)
+{
+	if (t->state != TOUCH_DISRUPT)
+		return;
+
+	tp_begin_touch(tp, t);
+}
+
+static inline void
+tp_detect_jumps(struct tp_dispatch *tp,
+		       struct tp_touch *t)
+{
+	/* Motivation: https://bugs.freedesktop.org/show_bug.cgi?id=76722 */
+
+	struct tp_motion *oldpos;
+	int dx, dy;
+
+	if (t->history.count == 0)
+		return;
+
+	/* This is called before tp_motion_history_push(),
+	   so the latest historical datum is at offset 0.
+	 */
+	oldpos = tp_motion_history_offset(t, 0);
+	dx = abs(t->x - oldpos->x);
+	dy = abs(t->y - oldpos->y);
+
+	if (dx > tp->jump_threshold || dy > tp->jump_threshold)
+		tp_disrupt_touch(tp, t);
+}
+
 static double
 tp_estimate_delta(int x0, int x1, int x2, int x3)
 {
@@ -407,6 +450,7 @@ tp_process_state(struct tp_dispatch *tp, uint32_t time)
 		} else if (!t->dirty)
 			continue;
 
+		tp_detect_jumps(tp, t);
 		tp_motion_hysteresis(tp, t);
 		tp_motion_history_push(t);
 	}
@@ -430,6 +474,8 @@ tp_post_process_state(struct tp_dispatch *tp, uint32_t time)
 		if (!t->dirty)
 			continue;
 
+		tp_undisrupt_touch(tp, t);
+
 		if (t->state == TOUCH_END) {
 			t->state = TOUCH_NONE;
 			t->fake = false;
@@ -776,6 +822,8 @@ tp_init(struct tp_dispatch *tp,
 	tp->hysteresis.margin_y =
 		diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
 
+	tp->jump_threshold = diagonal / DEFAULT_JUMP_DETECTION_DENOMINATOR;
+
 	if (libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE) ||
 	    libevdev_has_event_code(device->evdev, EV_KEY, BTN_RIGHT))
 		tp->buttons.has_buttons = true;
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 2bdb329..dc02014 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -43,6 +43,7 @@ enum touch_state {
 	TOUCH_NONE = 0,
 	TOUCH_BEGIN,
 	TOUCH_UPDATE,
+	TOUCH_DISRUPT,
 	TOUCH_END
 };
 
@@ -110,6 +111,8 @@ struct tp_dispatch {
 		int32_t margin_y;
 	} hysteresis;
 
+	int32_t jump_threshold;
+
 	struct motion_filter *filter;
 
 	struct {
-- 
1.8.5.2

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to