summaryrefslogtreecommitdiff
path: root/test/test-touchpad-tap.c
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2019-11-08 15:16:42 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2019-11-15 00:24:00 +0000
commit271616265b5f706af8e83677ab05d6a6be0425b0 (patch)
tree8490fbc0079a8b5c67ebb2468a9a4673e7256adf /test/test-touchpad-tap.c
parentc5f5a0fa7bc8793e1092d90fab1426bc3a3cd26f (diff)
downloadlibinput-271616265b5f706af8e83677ab05d6a6be0425b0.tar.gz
touchpad: don't allow for multifinger tapping after a move
In the current implementation, movements > threshold and timeouts usually move to HOLD state and continue from there. Where a finger is lifted, we go back up the diagram into the previous finger count's HOLD state. The side-effect of this is that a tap of a finger can be counted as tap even after a movement: - two fingers down, move to scroll, hold down - third finger down, third finger up This sequence triggers an erroneous three-finger tap. Once the motion threshold is hit by any touch, no finger must trigger 2/3 finger tap events while any touch is down. The false tap is only triggered where the new finger can execute a tap without any other finger changing any property. This can be triggered on the reporter's Dell Precision 5520 but on most other touchpads, a new finger down will trigger slight movement, pressure or touch size updates and thus the bug cannot be triggered. Fixes #382 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'test/test-touchpad-tap.c')
-rw-r--r--test/test-touchpad-tap.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/test/test-touchpad-tap.c b/test/test-touchpad-tap.c
index 08629083..cfb3dd45 100644
--- a/test/test-touchpad-tap.c
+++ b/test/test-touchpad-tap.c
@@ -2029,6 +2029,42 @@ START_TEST(touchpad_3fg_tap_slot_release_btntool)
}
END_TEST
+START_TEST(touchpad_3fg_tap_after_scroll)
+{
+ 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_2fg_scroll(dev);
+ litest_enable_tap(dev->libinput_device);
+
+ litest_touch_down(dev, 0, 40, 20);
+ litest_touch_down(dev, 1, 50, 20);
+ litest_drain_events(li);
+
+ /* 2fg scroll */
+ litest_touch_move_two_touches(dev, 40, 20, 50, 20, 0, 20, 10);
+ litest_drain_events(li);
+
+ litest_timeout_tap();
+ libinput_dispatch(li);
+
+ /* third finger tap without the other two fingers moving */
+ litest_touch_down(dev, 2, 60, 40);
+ libinput_dispatch(li);
+ litest_touch_up(dev, 2);
+ libinput_dispatch(li);
+
+ litest_timeout_tap();
+ libinput_dispatch(li);
+
+ litest_assert_empty_queue(li);
+}
+END_TEST
+
START_TEST(touchpad_4fg_tap)
{
struct litest_device *dev = litest_current_device();
@@ -2099,6 +2135,78 @@ START_TEST(touchpad_4fg_tap_quickrelease)
}
END_TEST
+START_TEST(touchpad_move_after_touch)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput *li = dev->libinput;
+ int nfingers = _i; /* ranged test */
+
+ if (libevdev_get_abs_maximum(dev->evdev, ABS_MT_SLOT) <= nfingers)
+ return;
+
+ litest_enable_tap(dev->libinput_device);
+ litest_drain_events(li);
+
+ /* respective number of fingers down */
+ switch(nfingers) {
+ case 5:
+ litest_touch_down(dev, 4, 70, 30);
+ /* fallthrough */
+ case 4:
+ litest_touch_down(dev, 3, 70, 30);
+ /* fallthrough */
+ case 3:
+ litest_touch_down(dev, 2, 60, 30);
+ /* fallthrough */
+ case 2:
+ litest_touch_down(dev, 1, 50, 30);
+ /* fallthrough */
+ case 1:
+ litest_touch_down(dev, 0, 40, 30);
+ /* fallthrough */
+ break;
+ default:
+ abort();
+ }
+
+ /* move finger 1 */
+ libinput_dispatch(li);
+ litest_touch_move_to(dev, 0, 70, 30, 70, 60, 10);
+ libinput_dispatch(li);
+
+ /* lift finger 1, put it back */
+ litest_touch_up(dev, 0);
+ libinput_dispatch(li);
+ litest_touch_down(dev, 0, 40, 30);
+ libinput_dispatch(li);
+
+ /* lift fingers up */
+ switch(nfingers) {
+ case 5:
+ litest_touch_up(dev, 4);
+ /* fallthrough */
+ case 4:
+ litest_touch_up(dev, 3);
+ /* fallthrough */
+ case 3:
+ litest_touch_up(dev, 2);
+ /* fallthrough */
+ case 2:
+ litest_touch_up(dev, 1);
+ /* fallthrough */
+ case 1:
+ litest_touch_up(dev, 0);
+ /* fallthrough */
+ break;
+ }
+ libinput_dispatch(li);
+ litest_timeout_tap();
+ libinput_dispatch(li);
+
+ litest_assert_no_typed_events(li, LIBINPUT_EVENT_POINTER_BUTTON);
+}
+END_TEST
+
START_TEST(touchpad_5fg_tap)
{
struct litest_device *dev = litest_current_device();
@@ -3560,6 +3668,7 @@ TEST_COLLECTION(touchpad_tap)
struct range range_2fg = {0, 2};
struct range range_3fg = {0, 3};
struct range range_4fg = {0, 4};
+ struct range range_multifinger = {2, 5};
litest_add("tap:1fg", touchpad_1fg_tap, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("tap:1fg", touchpad_1fg_doubletap, LITEST_TOUCHPAD, LITEST_ANY);
@@ -3600,12 +3709,15 @@ TEST_COLLECTION(touchpad_tap)
litest_add("tap:3fg", touchpad_3fg_tap_pressure_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add_for_device("tap:3fg", touchpad_3fg_tap_btntool_pointerjump, LITEST_SYNAPTICS_TOPBUTTONPAD);
litest_add_for_device("tap:3fg", touchpad_3fg_tap_slot_release_btntool, LITEST_SYNAPTICS_TOPBUTTONPAD);
+ litest_add("tap:3fg", touchpad_3fg_tap_after_scroll, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("tap:4fg", touchpad_4fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add("tap:4fg", touchpad_4fg_tap_quickrelease, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add("tap:5fg", touchpad_5fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
litest_add("tap:5fg", touchpad_5fg_tap_quickrelease, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT);
+ litest_add_ranged("tap:multifinger", touchpad_move_after_touch, LITEST_TOUCHPAD, LITEST_ANY, &range_multifinger);
+
/* Real buttons don't interfere with tapping, so don't run those for
pads with buttons */
litest_add("tap:1fg", touchpad_1fg_double_tap_click, LITEST_CLICKPAD, LITEST_ANY);