If a single-touch touchpad drops below the pressure threshold in the same frame where a fake finger is added, we begin a fake touch here. The subsequent loop ends this fake touch because real_fingers_down is 0.
This causes the tapping code to have a mismatch of how many fingers are down because it never sees the touch begin event for that finger. https://bugs.freedesktop.org/show_bug.cgi?id=105160 --- src/evdev-mt-touchpad-tap.c | 1 + src/evdev-mt-touchpad.c | 16 +++++++++------- test/test-touchpad-tap.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c index eaf3a573..fadc9535 100644 --- a/src/evdev-mt-touchpad-tap.c +++ b/src/evdev-mt-touchpad-tap.c @@ -1027,6 +1027,7 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time) } else if (t->state == TOUCH_END) { if (t->was_down) { + assert(tp->tap.nfingers_down >= 1); tp->tap.nfingers_down--; tp_tap_handle_event(tp, t, TAP_EVENT_RELEASE, time); } diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 02ad9dd8..b3ed6d56 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -1102,14 +1102,16 @@ tp_unhover_pressure(struct tp_dispatch *tp, uint64_t time) * _all_ fingers have enough pressure, even if some of the slotted * ones don't. Anything else gets insane quickly. */ - tp_for_each_touch(tp, t) { - if (t->state == TOUCH_HOVERING) { - /* avoid jumps when landing a finger */ - tp_motion_history_reset(t); - tp_begin_touch(tp, t, time); + if (real_fingers_down > 0) { + tp_for_each_touch(tp, t) { + if (t->state == TOUCH_HOVERING) { + /* avoid jumps when landing a finger */ + tp_motion_history_reset(t); + tp_begin_touch(tp, t, time); - if (tp->nfingers_down >= nfake_touches) - break; + if (tp->nfingers_down >= nfake_touches) + break; + } } } diff --git a/test/test-touchpad-tap.c b/test/test-touchpad-tap.c index 06caeb20..0616ae22 100644 --- a/test/test-touchpad-tap.c +++ b/test/test-touchpad-tap.c @@ -1591,6 +1591,48 @@ START_TEST(touchpad_3fg_tap_quickrelease) } END_TEST +START_TEST(touchpad_3fg_tap_hover_btntool) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + if (libevdev_get_abs_maximum(dev->evdev, + ABS_MT_SLOT) >= 2) + return; + + litest_enable_tap(dev->libinput_device); + litest_enable_edge_scroll(dev); + + litest_drain_events(li); + + litest_touch_down(dev, 0, 50, 50); + litest_touch_down(dev, 1, 70, 50); + libinput_dispatch(li); + + litest_touch_move_to(dev, 0, 50, 50, 50, 70, 10, 0); + litest_touch_move_to(dev, 1, 70, 50, 50, 70, 10, 0); + litest_drain_events(li); + + /* drop below the pressure threshold in the same frame as starting a */ + litest_event(dev, EV_ABS, ABS_MT_PRESSURE, 3); + litest_event(dev, EV_ABS, ABS_PRESSURE, 3); + litest_event(dev, EV_KEY, BTN_TOUCH, 0); + litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0); + litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + + litest_push_event_frame(dev); + litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1); + litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0); + litest_pop_event_frame(dev); + litest_assert_empty_queue(li); + + litest_touch_up(dev, 0); + litest_touch_up(dev, 1); +} +END_TEST + START_TEST(touchpad_3fg_tap_btntool) { struct litest_device *dev = litest_current_device(); @@ -3273,6 +3315,7 @@ litest_setup_tests_touchpad_tap(void) litest_add_ranged("tap-3fg:3fg", touchpad_3fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &tap_map_range); litest_add("tap-3fg:3fg", touchpad_3fg_tap_tap_again, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("tap-3fg:3fg", touchpad_3fg_tap_quickrelease, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add("tap-3fg:3fg", touchpad_3fg_tap_hover_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add_for_device("tap-3fg:3fg", touchpad_3fg_tap_btntool_pointerjump, LITEST_SYNAPTICS_TOPBUTTONPAD); litest_add("tap-4fg:4fg", touchpad_4fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT); litest_add("tap-4fg:4fg", touchpad_4fg_tap_quickrelease, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT); -- 2.14.3 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel