From: Peter Hutterer Date: Thu, 5 Apr 2018 01:18:40 +0000 (+1000) Subject: touchpad: don't process state for a touch in TOUCH_NONE X-Git-Tag: 1.10.4~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=201eaf3a8bd558c1685bc6254a8b59574a51ac34;p=platform%2Fupstream%2Flibinput.git touchpad: don't process state for a touch in TOUCH_NONE If a touch is in TOUCH_NONE, there is nothing to see here, please move along. In the case of bug 105696, we were accessing the speed.exceeded_count of a touch that was released previously, erroneously detecting a speed-based thumb. The sequence was: - touch down in slot 0, speed.exceeded_count is reset to 0 - move touch until exceeded_count is greater than our threshold - touch up in slot 0 - touch down in slot 1 [1] - touch down in slot 2 (more than 25mm away) - we counted the slot 0 speed.exceeded_count, labeling the slot 2 touch as speed-based thumb [1] peculiar behavior only observed on this device, usually slots get re-used at the first opportunity so having an inactive slot followed by higher slots being used is unusual. https://bugs.freedesktop.org/show_bug.cgi?id=105696 Signed-off-by: Peter Hutterer (cherry picked from commit 928bad9104f6270dc638022ba8cc20f42a0e1b41) --- diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 8a3923c7..cc01976a 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -1489,6 +1489,9 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time) want_motion_reset = tp_need_motion_history_reset(tp); tp_for_each_touch(tp, t) { + if (t->state == TOUCH_NONE) + continue; + if (want_motion_reset) { tp_motion_history_reset(t); t->quirks.reset_motion_history = true; diff --git a/test/test-touchpad.c b/test/test-touchpad.c index 4759bfb6..028af4c4 100644 --- a/test/test-touchpad.c +++ b/test/test-touchpad.c @@ -4487,6 +4487,43 @@ START_TEST(touchpad_thumb_moving) } END_TEST +START_TEST(touchpad_thumb_moving_empty_slots) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + litest_disable_tap(dev->libinput_device); + litest_enable_2fg_scroll(dev); + + if (libevdev_get_num_slots(dev->evdev) < 3) + return; + + litest_drain_events(li); + + /* exceed the speed movement threshold in slot 0 */ + litest_touch_down(dev, 0, 50, 20); + litest_touch_move_to(dev, 0, 50, 20, 70, 99, 15, 0); + litest_touch_up(dev, 0); + + litest_drain_events(li); + + /* scroll in slots 1 and 2 */ + litest_touch_down(dev, 1, 50, 50); + litest_touch_down(dev, 2, 90, 50); + libinput_dispatch(li); + for (int i = 0, y = 50; i < 10; i++, y++) { + litest_touch_move_to(dev, 1, 50, y, 50, y + 1, 1, 0); + litest_touch_move_to(dev, 2, 50, y, 50, y + 1, 1, 0); + } + libinput_dispatch(li); + litest_touch_up(dev, 1); + litest_touch_up(dev, 2); + libinput_dispatch(li); + litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 2); + +} +END_TEST + START_TEST(touchpad_thumb_clickfinger) { struct litest_device *dev = litest_current_device(); @@ -5898,6 +5935,7 @@ litest_setup_tests_touchpad(void) litest_add("touchpad:thumb", touchpad_thumb_begin_no_motion, LITEST_CLICKPAD, LITEST_ANY); litest_add("touchpad:thumb", touchpad_thumb_update_no_motion, LITEST_CLICKPAD, LITEST_ANY); litest_add("touchpad:thumb", touchpad_thumb_moving, LITEST_CLICKPAD, LITEST_ANY); + litest_add("touchpad:thumb", touchpad_thumb_moving_empty_slots, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:thumb", touchpad_thumb_clickfinger, LITEST_CLICKPAD, LITEST_ANY); litest_add("touchpad:thumb", touchpad_thumb_btnarea, LITEST_CLICKPAD, LITEST_ANY); litest_add("touchpad:thumb", touchpad_thumb_tap_begin, LITEST_CLICKPAD, LITEST_ANY);