[PATCH libinput 1/2] touchpad: sync the slot state after tp_resume()

Peter Hutterer peter.hutterer at who-t.net
Thu Jul 6 03:49:57 UTC 2017


If the touchpad is suspended and resumed (e.g. lid switch), the initial slot
state may be out of sync. If a touch happened while the touchpad was suspended
and the next touch down is on exactly the same x and/or y coordinate, our
touch point would still have the coordinates of the most recently seen touch
(i.e. before touchpad suspend). This could cause a pointer jump or test case
failures.

The real-world impact of this is minimal, putting the finger down in exactly
the same spot is virtually impossible. It could cause a test case failure in the
lid_disable_touchpad() test though, the second touch sequence was on the same
y coordinate and the touch location for that whole sequence was x/0.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad.c | 75 +++++++++++++++++++++++++++----------------------
 1 file changed, 42 insertions(+), 33 deletions(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 4d0cff97..2b9bc28b 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -1446,6 +1446,45 @@ tp_interface_suspend(struct evdev_dispatch *dispatch,
 	tp_clear_state(tp);
 }
 
+static inline void
+tp_sync_touch(struct tp_dispatch *tp,
+	      struct evdev_device *device,
+	      struct tp_touch *t,
+	      int slot)
+{
+	struct libevdev *evdev = device->evdev;
+
+	if (!libevdev_fetch_slot_value(evdev,
+				       slot,
+				       ABS_MT_POSITION_X,
+				       &t->point.x))
+		t->point.x = libevdev_get_event_value(evdev, EV_ABS, ABS_X);
+	if (!libevdev_fetch_slot_value(evdev,
+				       slot,
+				       ABS_MT_POSITION_Y,
+				       &t->point.y))
+		t->point.y = libevdev_get_event_value(evdev, EV_ABS, ABS_Y);
+
+	if (!libevdev_fetch_slot_value(evdev,
+				       slot,
+				       ABS_MT_PRESSURE,
+				       &t->pressure))
+		t->pressure = libevdev_get_event_value(evdev,
+						       EV_ABS,
+						       ABS_PRESSURE);
+}
+
+static void
+tp_sync_slots(struct tp_dispatch *tp,
+	      struct evdev_device *device)
+{
+	/* Always sync the first touch so we get ABS_X/Y synced on
+	 * single-touch touchpads */
+	tp_sync_touch(tp, device, &tp->touches[0], 0);
+	for (unsigned int i = 1; i < tp->num_slots; i++)
+		tp_sync_touch(tp, device, &tp->touches[i], i);
+}
+
 static void
 tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
 {
@@ -1458,6 +1497,8 @@ tp_resume(struct tp_dispatch *tp, struct evdev_device *device)
 	} else {
 		evdev_device_resume(device);
 	}
+
+	tp_sync_slots(tp, device);
 }
 
 static void
@@ -1912,34 +1953,6 @@ tp_init_touch(struct tp_dispatch *tp,
 	t->has_ended = true;
 }
 
-static void
-tp_sync_touch(struct tp_dispatch *tp,
-	      struct evdev_device *device,
-	      struct tp_touch *t,
-	      int slot)
-{
-	struct libevdev *evdev = device->evdev;
-
-	if (!libevdev_fetch_slot_value(evdev,
-				       slot,
-				       ABS_MT_POSITION_X,
-				       &t->point.x))
-		t->point.x = libevdev_get_event_value(evdev, EV_ABS, ABS_X);
-	if (!libevdev_fetch_slot_value(evdev,
-				       slot,
-				       ABS_MT_POSITION_Y,
-				       &t->point.y))
-		t->point.y = libevdev_get_event_value(evdev, EV_ABS, ABS_Y);
-
-	if (!libevdev_fetch_slot_value(evdev,
-				       slot,
-				       ABS_MT_PRESSURE,
-				       &t->pressure))
-		t->pressure = libevdev_get_event_value(evdev,
-						       EV_ABS,
-						       ABS_PRESSURE);
-}
-
 static inline void
 tp_disable_abs_mt(struct evdev_device *device)
 {
@@ -2025,11 +2038,7 @@ tp_init_slots(struct tp_dispatch *tp,
 	for (i = 0; i < tp->ntouches; i++)
 		tp_init_touch(tp, &tp->touches[i]);
 
-	/* Always sync the first touch so we get ABS_X/Y synced on
-	 * single-touch touchpads */
-	tp_sync_touch(tp, device, &tp->touches[0], 0);
-	for (i = 1; i < tp->num_slots; i++)
-		tp_sync_touch(tp, device, &tp->touches[i], i);
+	tp_sync_slots(tp, device);
 
 	/* Some touchpads don't reset BTN_TOOL_FINGER on touch up and only
 	 * change to/from it when BTN_TOOL_DOUBLETAP is set. This causes us
-- 
2.13.0



More information about the wayland-devel mailing list