diff --git a/doc/touchpad-tap-state-machine.svg b/doc/touchpad-tap-state-machine.svg index d4630c1f..4d6f64e6 100644 --- a/doc/touchpad-tap-state-machine.svg +++ b/doc/touchpad-tap-state-machine.svg @@ -1,3 +1,3 @@ -yesno(this section exists for [n] = 1, [n] = 2, and [n] = 3)noyesyes
IDLE
IDLE
firstfinger downTOUCH_TOUCHTOUCHsecondfinger downTOUCH_TOUCHTOUCH_2thirdfinger downTOUCH_TOUCHTOUCH_3TOUCH_2_RELEASEeitherfinger upremainingfinger upanyfinger upTOUCH_3_RELEASEeitherfinger upTOUCH_3_RELEASE_2remainingfinger upTOUCH_IDLETOUCH_IDLETOUCH_IDLETOUCH_IDLETOUCH_IDLEpalmTOUCH_DEADeitherfinger palmTOUCH_DEADanyfinger palmTOUCH_DEADeitherfinger palmTOUCH_DEADremainingfinger palmTOUCH_DEADremainingfinger palmTOUCH_DEAD2-finger tap3-finger tapfinger upTOUCH_IDLE1-finger tapfourthfinger down
IDLE
IDLE
TAPPEDyes2-finger tappalmfinger upbutton [n]pressbutton [n]releaseDRAGGING_OR_DOUBLETAPfinger downtap-and-dragtimeouttimeoutmove >thresholdDRAGGINGpalmfinger upnoyesdrag-lockenabled?DRAGLOCK_WAITDRAGLOCK_CONTINUEfinger uppalmtimeoutmove >thresholddrag-locktimeout1-finger tapyesnonon-palmfinger count== 0?finger down1-finger taptimeouttimeoutHOLD3-finger taptimeout3-finger tapTOUCH_2_HOLDTOUCH_3_HOLDtimeouttimeoutyestimeoutpalmfinger upTOUCH_DEADTOUCH_IDLEeitherfinger palmeitherfinger upTOUCH_DEADTOUCH_IDLEanyfinger palmanyfinger upTOUCH_DEADTOUCH_IDLETOUCH_DEADDEADBUTTONclickpadbuttonreleaseall fingersTOUCH_DEADnoyesnon-palmfinger count== 0?clickpadbuttonpressanyfinger upTOUCH_IDLEanyfinger palmmove >thresholdmove >thresholdmove >thresholdmove >thresholdmove >thresholdmove >thresholdmove >thresholdmove >thresholdmove >threshold3-finger tapclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpress1-finger tap3-finger tapbutton [n]releaseBUTTONclickpadbuttonreleaseclickpadbuttonpressbutton [n]releaseclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressbutton [n]press
[n] = 1
[n] = 1
[n] = 1
[n] = 1
[n] = 2
[n] = 2
[n] = 3
[n] = 3
notap-and-dragenabled?move >thresholdyesnonon-palmfinger count== 0?nonon-palmfinger count== 0?secondfinger downsecondfinger downset tap stateto DEADfinger downTOUCH_DEADthumbyesdrag state== IDLE?TOUCH_DEADthumbTOUCH_DEADnodrag state== IDLE?drag state== IDLE?3-finger tapfinger downTOUCH_TOUCH3-finger tapfinger downTOUCH_TOUCHfinger downTOUCH_TOUCH3-finger tapall fingersTOUCH_DEADfourthfinger downTOUCH_DEADto draggingstate machine:move >thresholdnodrag state== IDLE?to draggingstate machine:move >thresholdfinger downnoyesnon-palmfinger count> 2?
Viewer does not support full SVG 1.1
\ No newline at end of file +no(this section exists for [n] = 1, [n] = 2, and [n] = 3)nonoyesyesyes
IDLE
IDLE
firstfinger downTOUCH_TOUCHTOUCHsecondfinger downTOUCH_TOUCHTOUCH_2thirdfinger downTOUCH_TOUCHTOUCH_3TOUCH_2_RELEASEeitherfinger upremainingfinger upanyfinger upTOUCH_3_RELEASEeitherfinger upTOUCH_3_RELEASE_2remainingfinger upTOUCH_IDLETOUCH_IDLETOUCH_IDLETOUCH_IDLETOUCH_IDLEpalmTOUCH_DEADeitherfinger palmTOUCH_DEADanyfinger palmTOUCH_DEADeitherfinger palmTOUCH_DEADremainingfinger palmTOUCH_DEADremainingfinger palmTOUCH_DEAD2-finger tap3-finger tapfinger upTOUCH_IDLE1-finger tapfourthfinger down
IDLE
IDLE
TAPPEDyes2-finger tappalmfinger upbutton [n]pressbutton [n]releaseDRAGGING_OR_DOUBLETAPfinger downtap-and-dragtimeouttimeoutmove >thresholdDRAGGINGpalmfinger upnoyesdrag-lockenabled?DRAGLOCK_WAITDRAGLOCK_CONTINUEfinger uppalmtimeoutmove >thresholddrag-locktimeout1-finger tapyesnonon-palmfinger count== 0?finger down1-finger taptimeouttimeoutHOLD3-finger taptimeout3-finger tapTOUCH_2_HOLDTOUCH_3_HOLDtimeouttimeoutyestimeoutpalmfinger upTOUCH_DEADTOUCH_IDLEeitherfinger palmeitherfinger upTOUCH_DEADTOUCH_IDLEanyfinger palmanyfinger upTOUCH_DEADTOUCH_IDLETOUCH_DEADDEADBUTTONclickpadbuttonreleaseall fingersTOUCH_DEADnoyesnon-palmfinger count== 0?clickpadbuttonpressanyfinger upTOUCH_IDLEanyfinger palmmove >thresholdmove >thresholdmove >thresholdmove >thresholdmove >thresholdmove >thresholdmove >thresholdmove >thresholdmove >threshold3-finger tapclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpress1-finger tap3-finger tapbutton [n]releaseBUTTONclickpadbuttonreleaseclickpadbuttonpressbutton [n]releaseclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressclickpadbuttonpressbutton [n]press
[n] = 1
[n] = 1
[n] = 1
[n] = 1
[n] = 2
[n] = 2
[n] = 3
[n] = 3
notap-and-dragenabled?move >thresholdyesnonon-palmfinger count== 0?nonon-palmfinger count== 0?secondfinger downsecondfinger downset tap stateto DEADfinger downTOUCH_DEADthumbyesdrag state== IDLE?TOUCH_DEADthumbTOUCH_DEADnodrag state== IDLE?drag state== IDLE?drag state== IDLE?3-finger tapfinger downTOUCH_TOUCH3-finger tapfinger downTOUCH_TOUCHfinger downTOUCH_TOUCH3-finger tapall fingersTOUCH_DEADfourthfinger downTOUCH_DEADto draggingstate machine:move >thresholdnoyesdrag state== IDLE?to draggingstate machine:move >threshold
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c index 7077715b..0db0c626 100644 --- a/src/evdev-mt-touchpad-tap.c +++ b/src/evdev-mt-touchpad-tap.c @@ -429,13 +429,6 @@ tp_drag_dragging_handle_event(struct tp_dispatch *tp, switch (event) { case TAP_EVENT_TOUCH: - if (tp->tap.nfingers_down > 2) { - tp_tap_notify(tp, - time, - nfingers_tapped, - LIBINPUT_BUTTON_STATE_RELEASED); - tp->tap.drag_state = DRAG_STATE_IDLE; - } break; case TAP_EVENT_RELEASE: if (tp->tap.nfingers_down == 0) { @@ -1027,7 +1020,10 @@ tp_tap_touch3_handle_event(struct tp_dispatch *tp, tp_tap_move_to_dead(tp, t); break; case TAP_EVENT_TIMEOUT: - tp->tap.state = TAP_STATE_TOUCH_3_HOLD; + if (tp->tap.drag_state == DRAG_STATE_IDLE) + tp->tap.state = TAP_STATE_TOUCH_3_HOLD; + else + tp->tap.state = TAP_STATE_DEAD; tp_tap_clear_timer(tp); tp_gesture_tap_timeout(tp, time); break; @@ -1115,7 +1111,10 @@ tp_tap_touch3_release_handle_event(struct tp_dispatch *tp, break; case TAP_EVENT_TIMEOUT: tp_drag_handle_event(tp, t, TAP_EVENT_3FGTAP, time); - tp->tap.state = TAP_STATE_TOUCH_2_HOLD; + if (tp->tap.drag_state == DRAG_STATE_IDLE) + tp->tap.state = TAP_STATE_TOUCH_2_HOLD; + else + tp->tap.state = TAP_STATE_DEAD; break; case TAP_EVENT_BUTTON: tp_drag_handle_event(tp, t, TAP_EVENT_3FGTAP, time); @@ -1160,7 +1159,10 @@ tp_tap_touch3_release2_handle_event(struct tp_dispatch *tp, break; case TAP_EVENT_TIMEOUT: tp_drag_handle_event(tp, t, TAP_EVENT_3FGTAP, time); - tp->tap.state = TAP_STATE_HOLD; + if (tp->tap.drag_state == DRAG_STATE_IDLE) + tp->tap.state = TAP_STATE_HOLD; + else + tp->tap.state = TAP_STATE_DEAD; break; case TAP_EVENT_BUTTON: tp_drag_handle_event(tp, t, TAP_EVENT_3FGTAP, time); diff --git a/test/test-touchpad-tap.c b/test/test-touchpad-tap.c index 8536fbeb..9914ac21 100644 --- a/test/test-touchpad-tap.c +++ b/test/test-touchpad-tap.c @@ -1975,22 +1975,23 @@ START_TEST(touchpad_tap_n_drag_3fg_btntool) litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); - /* Putting down a third finger should end the drag */ + /* Putting down a third finger should not cause any events */ litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1); litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0); litest_event(dev, EV_SYN, SYN_REPORT, 0); litest_dispatch(li); - litest_assert_button_event(li, button, - LIBINPUT_BUTTON_STATE_RELEASED); + litest_assert_empty_queue(li); - /* Releasing the fingers should not cause any events */ + /* Releasing the fingers should end the drag */ litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0); litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1); litest_event(dev, EV_SYN, SYN_REPORT, 0); litest_touch_up(dev, 1); litest_touch_up(dev, 0); + litest_assert_button_event(li, button, + LIBINPUT_BUTTON_STATE_RELEASED); litest_assert_empty_queue(li); } END_TEST @@ -2069,19 +2070,20 @@ START_TEST(touchpad_tap_n_drag_3fg) litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); - /* Putting down a third finger should end the drag */ + /* Putting down a third finger should still do nothing */ litest_touch_down(dev, 2, 50, 50); litest_dispatch(li); - litest_assert_button_event(li, button, - LIBINPUT_BUTTON_STATE_RELEASED); + litest_assert_empty_queue(li); - /* Releasing the fingers should not cause any events */ + /* Releasing the fingers should end the drag */ litest_touch_up(dev, 2); litest_touch_up(dev, 1); litest_touch_up(dev, 0); + litest_assert_button_event(li, button, + LIBINPUT_BUTTON_STATE_RELEASED); litest_assert_empty_queue(li); } END_TEST