summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2018-02-28 12:51:27 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2018-03-01 12:24:48 +1000
commit6ccd8e934f965150173866db265ca544031c6e6b (patch)
tree32277d6af1b284637b3331daab6e5a012c22bb9b /test
parent3979b9e16a5ed141506d95f80ddfd7b94651dcfa (diff)
touchpad: add a TOUCH_MAYBE_END state
This state is used by the pre-processing of the touch states to indicate that the touch point has ended and is changed to TOUCH_END as soon as that pre-processing is finished. Sometimes we have to resurrect a touch point that has physically or logically ended but needs to be kept around to keep the BTN_TOOL_* fake finger count happy. Particularly on Synaptics touchpads, where a BTN_TOOL_TRIPLETAP can cause a touch point to end (i.e. 1 touch down + TRIPLETAP) but that touch restarts in the next sequence. We had a quirk for this in place already, but if we end the touch and then re-instate it with tp_begin_touch(), we may lose some information about thumb/palm/etc. states that touch already had. As a result, the state machines can get confused and a touch that was previously ignored as thumb suddenly isn't one anymore and triggers assertions. The specific sequence in bug 10528 is: * touch T1 down * touch T2 down, detected as speed-based thumb, tap state machine ignores it * frame F: TRIPLETAP down, touch T2 up * frame F+1: touch T2 down in next frame, but without the thumb bit * frame F+n: touch T2 ends, tap state machine gets confused because that touch should not trigger a release https://bugs.freedesktop.org/show_bug.cgi?id=105258 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Diffstat (limited to 'test')
-rw-r--r--test/test-touchpad.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/test/test-touchpad.c b/test/test-touchpad.c
index bf342b95..98f9b620 100644
--- a/test/test-touchpad.c
+++ b/test/test-touchpad.c
@@ -5423,6 +5423,72 @@ START_TEST(touchpad_pressure_tap_2fg_1fg_light)
}
END_TEST
+START_TEST(touchpad_pressure_btntool)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput *li = dev->libinput;
+ struct axis_replacement axes[] = {
+ { ABS_MT_PRESSURE, 5 },
+ { ABS_PRESSURE, 5 },
+ { -1, 0 }
+ };
+
+ /* we only have tripletap, can't test 4 slots because nothing will
+ * happen */
+ if (libevdev_get_num_slots(dev->evdev) != 2)
+ return;
+
+ if (!touchpad_has_pressure(dev))
+ return;
+
+ litest_enable_tap(dev->libinput_device);
+ litest_drain_events(li);
+
+ /* Two light touches down, doesn't count */
+ litest_touch_down_extended(dev, 0, 40, 50, axes);
+ litest_touch_down_extended(dev, 1, 45, 50, axes);
+ libinput_dispatch(li);
+ litest_assert_empty_queue(li);
+
+ /* Tripletap but since no finger is logically down, it doesn't count */
+ 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);
+ litest_assert_empty_queue(li);
+
+ /* back to two fingers */
+ litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
+ litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
+ libinput_dispatch(li);
+
+ /* make one finger real */
+ litest_touch_move_to(dev, 0, 40, 50, 41, 52, 10, 10);
+ litest_drain_events(li);
+
+ /* tripletap should now be 3 fingers tap */
+ 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_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1);
+ litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0);
+ litest_event(dev, EV_SYN, SYN_REPORT, 0);
+ libinput_dispatch(li);
+
+ litest_timeout_tap();
+ libinput_dispatch(li);
+
+ litest_assert_button_event(li,
+ BTN_MIDDLE,
+ LIBINPUT_BUTTON_STATE_PRESSED);
+ litest_assert_button_event(li,
+ BTN_MIDDLE,
+ LIBINPUT_BUTTON_STATE_RELEASED);
+}
+END_TEST
+
static inline bool
touchpad_has_touch_size(struct litest_device *dev)
{
@@ -5806,6 +5872,7 @@ litest_setup_tests_touchpad(void)
litest_add("touchpad:pressure", touchpad_pressure_tap, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:pressure", touchpad_pressure_tap_2fg, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:pressure", touchpad_pressure_tap_2fg_1fg_light, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
+ litest_add("touchpad:pressure", touchpad_pressure_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:touch-size", touchpad_touch_size, LITEST_APPLE_CLICKPAD, LITEST_ANY);
litest_add("touchpad:touch-size", touchpad_touch_size_2fg, LITEST_APPLE_CLICKPAD, LITEST_ANY);