summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2020-02-18 16:48:09 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2020-02-18 17:11:35 +1000
commit06591e5913fdfbc5eee4a7eb7ff035940ab99d81 (patch)
tree23a46f5b1022269becc0c9a347a6f79607d96af2
parent1e1b9c0e6085ba9b4259597dfec78f5b7fb34d99 (diff)
touchpad: sync the initial tracking id state to the touchpad
Where fingers are down during startup we need to sync them to the known state of the device so our slot count is correct. Otherwise, when the fingers are lifted we will trigger the new assert for nactive_slots being less than 0. Regression introduced in eb6ef9fe70635e7c91e8bb860b5a282f4cd3f91e Fixes #429 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--src/evdev-mt-touchpad.c8
-rw-r--r--test/test-touchpad.c59
2 files changed, 67 insertions, 0 deletions
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index b2a96548..a18cbeda 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -2063,6 +2063,7 @@ tp_sync_touch(struct tp_dispatch *tp,
int slot)
{
struct libevdev *evdev = device->evdev;
+ int tracking_id;
if (!libevdev_fetch_slot_value(evdev,
slot,
@@ -2091,6 +2092,13 @@ tp_sync_touch(struct tp_dispatch *tp,
slot,
ABS_MT_TOUCH_MINOR,
&t->minor);
+
+ if (libevdev_fetch_slot_value(evdev,
+ slot,
+ ABS_MT_TRACKING_ID,
+ &tracking_id) &&
+ tracking_id != -1)
+ tp->nactive_slots++;
}
static void
diff --git a/test/test-touchpad.c b/test/test-touchpad.c
index 06dff514..d25052d4 100644
--- a/test/test-touchpad.c
+++ b/test/test-touchpad.c
@@ -3570,6 +3570,63 @@ START_TEST(touchpad_initial_state)
}
END_TEST
+START_TEST(touchpad_fingers_down_before_init)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput *li;
+
+ int finger_count = _i; /* looped test */
+ unsigned int map[] = {0, BTN_TOOL_PEN, BTN_TOOL_DOUBLETAP,
+ BTN_TOOL_TRIPLETAP, BTN_TOOL_QUADTAP,
+ BTN_TOOL_QUINTTAP};
+
+ dev = litest_current_device();
+
+ if (!libevdev_has_event_code(dev->evdev, EV_KEY, map[finger_count]))
+ return;
+
+ /* Fingers down but before we have the real context */
+ for (int i = 0; i < finger_count; i++) {
+ if (litest_slot_count(dev) >= finger_count) {
+ litest_touch_down(dev, i, 20 + 10 * i, 30);
+ } else {
+ litest_event(dev, EV_KEY, map[finger_count], 1);
+ }
+ }
+
+ litest_drain_events(dev->libinput);
+
+ /* create anew context that already has the fingers down */
+ li = litest_create_context();
+ libinput_path_add_device(li,
+ libevdev_uinput_get_devnode(dev->uinput));
+ litest_drain_events(li);
+
+ for (int x = 0; x < 10; x++) {
+ for (int i = 0; i < finger_count; i++) {
+ if (litest_slot_count(dev) < finger_count)
+ break;
+ litest_touch_move(dev, i, 20 + 10 * i + x, 30);
+ }
+ }
+ libinput_dispatch(li);
+ litest_assert_empty_queue(li);
+
+ for (int i = 0; i < finger_count; i++) {
+ if (litest_slot_count(dev) >= finger_count) {
+ litest_touch_up(dev, i);
+ } else {
+ litest_event(dev, EV_KEY, map[finger_count], 0);
+ }
+ }
+
+ litest_assert_empty_queue(li);
+
+ libinput_unref(li);
+}
+END_TEST
+
+
/* This just tests that we don't completely screw up in one specific case.
* The test likely needs to be removed if it starts failing in the future.
*
@@ -6940,6 +6997,7 @@ TEST_COLLECTION(touchpad)
struct range suspends = { SUSPEND_EXT_MOUSE, SUSPEND_COUNT };
struct range axis_range = {ABS_X, ABS_Y + 1};
struct range twice = {0, 2 };
+ struct range five_fingers = {1, 6};
litest_add("touchpad:motion", touchpad_1fg_motion, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:motion", touchpad_2fg_no_motion, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
@@ -7052,6 +7110,7 @@ TEST_COLLECTION(touchpad)
litest_add_for_device("touchpad:trackpoint", touchpad_trackpoint_no_trackpoint, LITEST_SYNAPTICS_TRACKPOINT_BUTTONS);
litest_add_ranged("touchpad:state", touchpad_initial_state, LITEST_TOUCHPAD, LITEST_ANY, &axis_range);
+ litest_add_ranged("touchpad:state", touchpad_fingers_down_before_init, LITEST_TOUCHPAD, LITEST_ANY, &five_fingers);
litest_add("touchpad:state", touchpad_state_after_syn_dropped_2fg_change, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:dwt", touchpad_dwt, LITEST_TOUCHPAD, LITEST_ANY);