From: Jonas Ådahl Date: Sun, 27 Jul 2014 21:28:31 +0000 (+0200) Subject: touchpad: Only break out of tap FSM for clickpad button presses X-Git-Tag: 0.6.0~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=94c59ef2014e9f81ed63d47367bae43221702253;p=platform%2Fupstream%2Flibinput.git touchpad: Only break out of tap FSM for clickpad button presses It should be possible to initiate a drag by tapping-drag, but continue it by pressing a physical button continuing to drag by subsequent finger motions. As the generic evdev layer helps us ignore multiple button presses we can have the tap machine run completely separate from and uneffected by regular physical button presses, making the tap FSM much simpler than adding new states for handling button presse life times from outside of the tap state machine. A touchpad test is updated to test click while tapping instead of tap FSM break out. The updated test is re-added but only for clickpads only. The tap FSM svg is updated to say "clickpad button press" instead of "phys button press". Signed-off-by: Jonas Ådahl Signed-off-by: Peter Hutterer Reviewed-by: Hans de Goede --- diff --git a/doc/touchpad-tap-state-machine.svg b/doc/touchpad-tap-state-machine.svg index 10739c68..7aecefc1 100644 --- a/doc/touchpad-tap-state-machine.svg +++ b/doc/touchpad-tap-state-machine.svg @@ -2,755 +2,755 @@ - - - - - - - + + + + + + + - IDLE + IDLE - + - TOUCH + TOUCH - + - first - finger down + first + finger down - - - + + + - finger up + finger up - - - + + + - button 1 - press + button 1 + press - + - timeout + timeout - - - + + + - move > - threshold + move > + threshold - - - + + + - second - finger down + second + finger down - - - + + + - TOUCH_2 + TOUCH_2 - + - second - finger up + second + finger up - - - + + + - button 2 - press + button 2 + press - + - move > - threshold + move > + threshold - + - timeout + timeout - - - - - + + + + + - button 1 - release + button 1 + release - + - button 2 - release + button 2 + release - - - - - + + + + + - TAPPED + TAPPED - + - timeout + timeout - - - + + + - first - finger down + first + finger down - - - + + + - DRAGGING + DRAGGING - + - first - finger up + first + finger up - + - btn1 - release + btn1 + release - - - - - - - + + + + + + + - IDLE + IDLE - + - third - finger down + third + finger down - - - + + + - TOUCH_3 + TOUCH_3 - - - + + + - button 3 - press + button 3 + press - + - button 3 - release + button 3 + release - - - + + + - move > - threshold + move > + threshold - - - + + + - IDLE + IDLE - + - timeout + timeout - - - + + + - first - finger up + first + finger up - - - + + + - IDLE + IDLE - + - fourth - finger down + fourth + finger down - - - - - + + + + + - DRAGGING_OR_DOUBLETAP + DRAGGING_OR_DOUBLETAP - - - + + + - timeout + timeout - - - + + + - first - finger up + first + finger up - - - + + + - button 1 - release + button 1 + release - + - button 1 - press + button 1 + press - + - btn1 - release + btn1 + release - - - - - - - - - + + + + + + + + + - second - finger down + second + finger down - - - + + + - move > - threshold + move > + threshold - - - - - + + + + + - HOLD + HOLD - + - first - finger up + first + finger up - - - - - + + + + + - second - finger down + second + finger down - - - - - - - + + + + + + + - TOUCH_2_HOLD + TOUCH_2_HOLD - + - second - finger up + second + finger up - - - + + + - first - finger up + first + finger up - - - - - - - + + + + + + + - third - finger down + third + finger down - - - - - - - + + + + + + + - TOUCH_3_HOLD + TOUCH_3_HOLD - - - + + + - fourth - finger down + fourth + finger down - + - DEAD + DEAD - - - - - - - + + + + + + + - any finger up + any finger up - + - fourth - finger up + fourth + finger up - + - any finger up + any finger up - - - - + + + + - - yes - - - - any finger up - - - - - - - - - - - - IDLE - - - - if finger - count == 0 - - - - - - - - - - second - finger up - - - - DRAGGING_2 - - - - - - - - first - finger up - - - - - - - - - - second - finger down - - - - - - - - - - third - finger down - - - - - - btn1 - release - - - - + + yes + + + + any finger up + + + + + + + + + + + + IDLE + + + + if finger + count == 0 + + + + + + + + + + second + finger up + + + + DRAGGING_2 + + + + + + + + first + finger up + + + + + + + + + + second + finger down + + + + + + + + + + third + finger down + + + + + + btn1 + release + + + + - phys - button - press - - - - - - - - - - - - - - + clickpad + button + press + + + + + + + + + + + + + + - phys - button - press - - - - - - button 1 - release - - - - - - - - - - - - - - DRAGGING_WAIT - - - - timeout - - - - - - - - - - first - finger down - - - - - - TOUCH_TOUCH - - - - TOUCH_IDLE - - - - - - - - - - - - TOUCH_DEAD - - - - - - - - - - - + clickpad + button + press + + + + + + button 1 + release + + + + + + + + + + + + + + DRAGGING_WAIT + + + + timeout + + + + + + + + + + first + finger down + + + + + + TOUCH_TOUCH + + + + TOUCH_IDLE + + + + + + + + + + + + TOUCH_DEAD + + + + + + + + + + + - - yes + + yes - + - TOUCH_DEAD + TOUCH_DEAD - - - - - - - + + + + + + + - TOUCH_IDLE + TOUCH_IDLE - - - + + + - TOUCH_TOUCH + TOUCH_TOUCH - - - - - + + + + + - TOUCH_IDLE + TOUCH_IDLE - - - + + + - TOUCH_IDLE + TOUCH_IDLE - - - + + + - TOUCH_IDLE + TOUCH_IDLE - - - + + + - TOUCH_TOUCH + TOUCH_TOUCH - - - + + + - that finger - TOUCH_IDLE + that finger + TOUCH_IDLE - - - + + + - TOUCH_DEAD + TOUCH_DEAD - - - - - - - + + + + + + + - that finger - TOUCH_IDLE + that finger + TOUCH_IDLE - - - - + + + + - - no + + no - + - TOUCH_TOUCH + TOUCH_TOUCH - - - + + + - TOUCH_IDLE + TOUCH_IDLE - - - + + + - TOUCH_TOUCH + TOUCH_TOUCH - - - + + + - TOUCH_DEAD + TOUCH_DEAD - - - - - + + + + + - TOUCH_IDLE + TOUCH_IDLE - - - + + + - TOUCH_TOUCH + TOUCH_TOUCH - - - - - + + + + + - TOUCH_TOUCH + TOUCH_TOUCH - - - + + + - TOUCH_IDLE + TOUCH_IDLE - - - + + + - TOUCH_IDLE + TOUCH_IDLE - - - + + + - TOUCH_TOUCH + TOUCH_TOUCH - - - + + + - TOUCH_IDLE + TOUCH_IDLE - - - + + + - TOUCH_TOUCH + TOUCH_TOUCH - - - + + + - that finger - TOUCH_IDLE + that finger + TOUCH_IDLE - - - + + + - TOUCH_DEAD + TOUCH_DEAD - - - + + + - TOUCH_DEAD + TOUCH_DEAD - + - TOUCH_DEAD + TOUCH_DEAD - + - TOUCH_DEAD + TOUCH_DEAD - - - + + + - TOUCH_DEAD + TOUCH_DEAD - - - + + + - TOUCH_DEAD + TOUCH_DEAD - - - + + + - state == - TOUCH_TOUCH + state == + TOUCH_TOUCH - + - that finger state == - TOUCH_TOUCH + that finger state == + TOUCH_TOUCH - - + + - - no + + no - + - TOUCH_DEAD + TOUCH_DEAD - - - + + + - TOUCH_DEAD + TOUCH_DEAD - + - TOUCH_DEAD + TOUCH_DEAD diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c index c05b45ce..357a50a6 100644 --- a/src/evdev-mt-touchpad-tap.c +++ b/src/evdev-mt-touchpad-tap.c @@ -542,7 +542,10 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time) struct tp_touch *t; int filter_motion = 0; - if (tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS) + /* Handle queued button pressed events from clickpads. For touchpads + * with separate physical buttons, ignore button pressed events so they + * don't interfere with tapping. */ + if (tp->buttons.is_clickpad && tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS) tp_tap_handle_event(tp, NULL, TAP_EVENT_BUTTON, time); tp_for_each_touch(tp, t) { diff --git a/test/touchpad.c b/test/touchpad.c index 86b2c91b..eae92025 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -256,14 +256,17 @@ START_TEST(touchpad_1fg_tap_click) litest_drain_events(dev->libinput); - /* finger down, button click, finger up - -> only one button left event pair */ + /* Finger down, finger up -> tap button press + * Physical button click -> no button press/release + * Tap timeout -> tap button release */ litest_touch_down(dev, 0, 50, 50); + litest_touch_up(dev, 0); litest_event(dev, EV_KEY, BTN_LEFT, 1); litest_event(dev, EV_SYN, SYN_REPORT, 0); litest_event(dev, EV_KEY, BTN_LEFT, 0); litest_event(dev, EV_SYN, SYN_REPORT, 0); - litest_touch_up(dev, 0); + libinput_dispatch(li); + msleep(200); libinput_dispatch(li); @@ -286,6 +289,42 @@ START_TEST(touchpad_2fg_tap_click) litest_drain_events(dev->libinput); + /* two fingers down, left button click, fingers up + -> one left button, one right button event pair */ + litest_touch_down(dev, 0, 50, 50); + litest_touch_down(dev, 1, 70, 50); + litest_event(dev, EV_KEY, BTN_LEFT, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_event(dev, EV_KEY, BTN_LEFT, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_touch_up(dev, 1); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + + assert_button_event(li, BTN_LEFT, + LIBINPUT_BUTTON_STATE_PRESSED); + assert_button_event(li, BTN_LEFT, + LIBINPUT_BUTTON_STATE_RELEASED); + assert_button_event(li, BTN_RIGHT, + LIBINPUT_BUTTON_STATE_PRESSED); + assert_button_event(li, BTN_RIGHT, + LIBINPUT_BUTTON_STATE_RELEASED); + + litest_assert_empty_queue(li); +} +END_TEST + +START_TEST(clickpad_2fg_tap_click) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + libinput_device_config_tap_set_enabled(dev->libinput_device, + LIBINPUT_CONFIG_TAP_ENABLED); + + litest_drain_events(dev->libinput); + /* two fingers down, button click, fingers up -> only one button left event pair */ litest_touch_down(dev, 0, 50, 50); @@ -684,6 +723,38 @@ START_TEST(touchpad_btn_left) } END_TEST +START_TEST(clickpad_1fg_tap_click) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + libinput_device_config_tap_set_enabled(dev->libinput_device, + LIBINPUT_CONFIG_TAP_ENABLED); + + litest_drain_events(dev->libinput); + + /* finger down, button click, finger up + -> only one button left event pair */ + litest_touch_down(dev, 0, 50, 50); + litest_event(dev, EV_KEY, BTN_LEFT, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_event(dev, EV_KEY, BTN_LEFT, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_touch_up(dev, 0); + libinput_dispatch(li); + msleep(200); + + libinput_dispatch(li); + + assert_button_event(li, BTN_LEFT, + LIBINPUT_BUTTON_STATE_PRESSED); + assert_button_event(li, BTN_LEFT, + LIBINPUT_BUTTON_STATE_RELEASED); + + litest_assert_empty_queue(li); +} +END_TEST + START_TEST(clickpad_btn_left) { struct litest_device *dev = litest_current_device(); @@ -1553,8 +1624,9 @@ int main(int argc, char **argv) { litest_add("touchpad:tap", touchpad_1fg_tap_n_drag, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:tap", touchpad_2fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:tap", touchpad_2fg_tap_inverted, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); - litest_add("touchpad:tap", touchpad_1fg_tap_click, LITEST_TOUCHPAD, LITEST_ANY); - litest_add("touchpad:tap", touchpad_2fg_tap_click, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_APPLE_CLICKPAD); + litest_add("touchpad:tap", touchpad_1fg_tap_click, LITEST_TOUCHPAD, LITEST_CLICKPAD); + litest_add("touchpad:tap", touchpad_2fg_tap_click, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_CLICKPAD); + litest_add("touchpad:tap", touchpad_2fg_tap_click_apple, LITEST_APPLE_CLICKPAD, LITEST_ANY); litest_add("touchpad:tap", touchpad_no_2fg_tap_after_move, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:tap", touchpad_no_2fg_tap_after_timeout, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); @@ -1575,6 +1647,9 @@ int main(int argc, char **argv) { litest_add("touchpad:tap", touchpad_tap_is_available, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:tap", touchpad_tap_is_not_available, LITEST_ANY, LITEST_TOUCHPAD); + litest_add("touchpad:tap", clickpad_1fg_tap_click, LITEST_CLICKPAD, LITEST_ANY); + litest_add("touchpad:tap", clickpad_2fg_tap_click, LITEST_CLICKPAD, LITEST_SINGLE_TOUCH|LITEST_APPLE_CLICKPAD); + litest_add_no_device("touchpad:clickfinger", touchpad_1fg_clickfinger); litest_add_no_device("touchpad:clickfinger", touchpad_2fg_clickfinger);