diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index af2a2cd1..05e2ae54 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -1829,6 +1829,14 @@ tp_init_slots(struct tp_dispatch *tp, for (i = 1; i < tp->num_slots; i++) tp_sync_touch(tp, device, &tp->touches[i], i); + /* 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 + * to ignore the first touches events until a two-finger gesture is + * performed. + */ + if (libevdev_get_event_value(device->evdev, EV_KEY, BTN_TOOL_FINGER)) + tp_fake_finger_set(tp, BTN_TOOL_FINGER, 1); + return true; } diff --git a/test/touchpad.c b/test/touchpad.c index cdc261bc..5b6f0a4e 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -4365,6 +4365,29 @@ START_TEST(touchpad_slot_swap) } END_TEST +START_TEST(touchpad_finger_always_down) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li; + + /* Set BTN_TOOL_FINGER before a new context is initialized */ + litest_event(dev, EV_KEY, BTN_TOOL_FINGER, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + + li = litest_create_context(); + libinput_path_add_device(li, + libevdev_uinput_get_devnode(dev->uinput)); + litest_drain_events(li); + + litest_touch_down(dev, 0, 50, 50); + litest_touch_move_to(dev, 0, 50, 50, 70, 50, 10, 0); + + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); + + libinput_unref(li); +} +END_TEST + START_TEST(touchpad_time_usec) { struct litest_device *dev = litest_current_device(); @@ -4742,6 +4765,7 @@ litest_setup_tests_touchpad(void) litest_add_for_device("touchpad:bugs", touchpad_tool_tripletap_touch_count, LITEST_SYNAPTICS_TOPBUTTONPAD); litest_add_for_device("touchpad:bugs", touchpad_slot_swap, LITEST_SYNAPTICS_TOPBUTTONPAD); + litest_add_for_device("touchpad:bugs", touchpad_finger_always_down, LITEST_SYNAPTICS_TOPBUTTONPAD); litest_add("touchpad:time", touchpad_time_usec, LITEST_TOUCHPAD, LITEST_ANY);