2014-03-29 0:16 GMT+06:00 Alexander E. Patrakov <patra...@gmail.com>:
> 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.

And now rebased on top of your wip/clickpad-improvements branch (which
works otherwise). Note that now I can get a right-click both using a
software button area and using a two-finger tap. Is this intentional?

-- 
Alexander E. Patrakov
From 3af1ca9d2aed569a171f9323a95aa5ee4fe6d85e 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 | 51 ++++++++++++++++++++++++++++++++++++++++++++++++-
 src/evdev-mt-touchpad.h |  3 +++
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index de7a7e1..9cb2531 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)
 {
@@ -353,7 +396,8 @@ tp_unpin_finger(struct tp_dispatch *tp, struct tp_touch *t)
 
 	t->pinned.state = PIN_STATE_NONE;
 
-	if (t->state != TOUCH_END && tp->nfingers_down == 1)
+	if (t->state != TOUCH_END && t->state != TOUCH_DISRUPT &&
+				tp->nfingers_down == 1)
 		t->is_pointer = true;
 }
 
@@ -417,6 +461,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);
 
@@ -447,6 +492,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;
@@ -742,6 +789,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 (tp_init_scroll(tp) != 0)
 		return -1;
 
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index fa4d932..70a9bb9 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
 };
 
@@ -147,6 +148,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