touchpad: track the release of all fingers in a three-finger tap
authorsatrmb <10471-satrmb_true-email-is-private_contact-via-web@gitlab.freedesktop.org>
Wed, 1 Jul 2020 09:54:28 +0000 (11:54 +0200)
committerPeter Hutterer <peter.hutterer@who-t.net>
Fri, 25 Sep 2020 06:01:28 +0000 (06:01 +0000)
This is in preparation for three-finger tap-and-drag, which will start from
a completed tap with no fingers down.

Signed-off-by: satrmb <10471-satrmb@users.noreply.gitlab.freedesktop.org>
src/evdev-mt-touchpad-tap.c
src/evdev-mt-touchpad.h

index f5cf73149e7eb1ad2f00b704d0a9bb10e4b11b3f..8ee0089c00f2304c7434cdbd59fe01b34a600b89 100644 (file)
@@ -66,6 +66,8 @@ tap_state_to_str(enum tp_tap_state state)
        CASE_RETURN_STRING(TAP_STATE_TOUCH_2_RELEASE);
        CASE_RETURN_STRING(TAP_STATE_TOUCH_3);
        CASE_RETURN_STRING(TAP_STATE_TOUCH_3_HOLD);
+       CASE_RETURN_STRING(TAP_STATE_TOUCH_3_RELEASE);
+       CASE_RETURN_STRING(TAP_STATE_TOUCH_3_RELEASE_2);
        CASE_RETURN_STRING(TAP_STATE_DRAGGING);
        CASE_RETURN_STRING(TAP_STATE_DRAGGING_WAIT);
        CASE_RETURN_STRING(TAP_STATE_DRAGGING_OR_DOUBLETAP);
@@ -439,11 +441,10 @@ tp_tap_touch2_release_handle_event(struct tp_dispatch *tp,
                              LIBINPUT_BUTTON_STATE_PRESSED);
                if (tp->tap.drag_enabled) {
                        tp->tap.state = TAP_STATE_TAPPED;
-                       tp->tap.saved_release_time = time;
                        tp_tap_set_timer(tp, time);
                } else {
                        tp_tap_notify(tp,
-                                     time,
+                                     tp->tap.saved_release_time,
                                      1,
                                      LIBINPUT_BUTTON_STATE_RELEASED);
                        tp->tap.state = TAP_STATE_IDLE;
@@ -473,14 +474,9 @@ tp_tap_touch3_handle_event(struct tp_dispatch *tp,
                tp_tap_clear_timer(tp);
                break;
        case TAP_EVENT_RELEASE:
-               tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
-               if (t->tap.state == TAP_TOUCH_STATE_TOUCH) {
-                       tp_tap_notify(tp,
-                                     tp->tap.saved_press_time,
-                                     3,
-                                     LIBINPUT_BUTTON_STATE_PRESSED);
-                       tp_tap_notify(tp, time, 3, LIBINPUT_BUTTON_STATE_RELEASED);
-               }
+               tp->tap.state = TAP_STATE_TOUCH_3_RELEASE;
+               tp->tap.saved_release_time = time;
+               tp_tap_set_timer(tp, time);
                break;
        case TAP_EVENT_BUTTON:
                tp->tap.state = TAP_STATE_DEAD;
@@ -527,6 +523,139 @@ tp_tap_touch3_hold_handle_event(struct tp_dispatch *tp,
        }
 }
 
+static void
+tp_tap_touch3_release_handle_event(struct tp_dispatch *tp,
+                                  struct tp_touch *t,
+                                  enum tap_event event, uint64_t time)
+{
+
+       switch (event) {
+       case TAP_EVENT_TOUCH:
+               tp_tap_notify(tp,
+                             tp->tap.saved_press_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_PRESSED);
+               tp_tap_notify(tp,
+                             tp->tap.saved_release_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_RELEASED);
+               tp->tap.state = TAP_STATE_TOUCH_3;
+               tp->tap.saved_press_time = time;
+               tp_tap_set_timer(tp, time);
+               break;
+       case TAP_EVENT_RELEASE:
+               tp->tap.state = TAP_STATE_TOUCH_3_RELEASE_2;
+               tp_tap_set_timer(tp, time);
+               break;
+       case TAP_EVENT_MOTION:
+               tp_tap_notify(tp,
+                             tp->tap.saved_press_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_PRESSED);
+               tp_tap_notify(tp,
+                             tp->tap.saved_release_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_RELEASED);
+               tp_tap_move_to_dead(tp, t);
+               break;
+       case TAP_EVENT_TIMEOUT:
+               tp_tap_notify(tp,
+                             tp->tap.saved_press_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_PRESSED);
+               tp_tap_notify(tp,
+                             tp->tap.saved_release_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_RELEASED);
+               tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
+               break;
+       case TAP_EVENT_BUTTON:
+               tp->tap.state = TAP_STATE_DEAD;
+               break;
+       case TAP_EVENT_THUMB:
+               break;
+       case TAP_EVENT_PALM:
+               tp->tap.state = TAP_STATE_TOUCH_2_RELEASE;
+               break;
+       case TAP_EVENT_PALM_UP:
+               break;
+       }
+}
+
+static void
+tp_tap_touch3_release2_handle_event(struct tp_dispatch *tp,
+                                   struct tp_touch *t,
+                                   enum tap_event event, uint64_t time)
+{
+
+       switch (event) {
+       case TAP_EVENT_TOUCH:
+               tp_tap_notify(tp,
+                             tp->tap.saved_press_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_PRESSED);
+               tp_tap_notify(tp,
+                             tp->tap.saved_release_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_RELEASED);
+               tp->tap.state = TAP_STATE_TOUCH_2;
+               tp->tap.saved_press_time = time;
+               tp_tap_set_timer(tp, time);
+               break;
+       case TAP_EVENT_RELEASE:
+               tp_tap_notify(tp,
+                             tp->tap.saved_press_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_PRESSED);
+               tp_tap_notify(tp,
+                             tp->tap.saved_release_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_RELEASED);
+               tp->tap.state = TAP_STATE_IDLE;
+               break;
+       case TAP_EVENT_MOTION:
+               tp_tap_notify(tp,
+                             tp->tap.saved_press_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_PRESSED);
+               tp_tap_notify(tp,
+                             tp->tap.saved_release_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_RELEASED);
+               tp_tap_move_to_dead(tp, t);
+               break;
+       case TAP_EVENT_TIMEOUT:
+               tp_tap_notify(tp,
+                             tp->tap.saved_press_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_PRESSED);
+               tp_tap_notify(tp,
+                             tp->tap.saved_release_time,
+                             3,
+                             LIBINPUT_BUTTON_STATE_RELEASED);
+               tp->tap.state = TAP_STATE_HOLD;
+               break;
+       case TAP_EVENT_BUTTON:
+               tp->tap.state = TAP_STATE_DEAD;
+               break;
+       case TAP_EVENT_THUMB:
+               break;
+       case TAP_EVENT_PALM:
+               tp_tap_notify(tp,
+                             tp->tap.saved_press_time,
+                             2,
+                             LIBINPUT_BUTTON_STATE_PRESSED);
+               tp_tap_notify(tp,
+                             tp->tap.saved_release_time,
+                             2,
+                             LIBINPUT_BUTTON_STATE_RELEASED);
+               tp->tap.state = TAP_STATE_IDLE;
+               break;
+       case TAP_EVENT_PALM_UP:
+               break;
+       }
+}
+
 static void
 tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp,
                                          struct tp_touch *t,
@@ -778,6 +907,12 @@ tp_tap_handle_event(struct tp_dispatch *tp,
        case TAP_STATE_TOUCH_3_HOLD:
                tp_tap_touch3_hold_handle_event(tp, t, event, time);
                break;
+       case TAP_STATE_TOUCH_3_RELEASE:
+               tp_tap_touch3_release_handle_event(tp, t, event, time);
+               break;
+       case TAP_STATE_TOUCH_3_RELEASE_2:
+               tp_tap_touch3_release2_handle_event(tp, t, event, time);
+               break;
        case TAP_STATE_DRAGGING_OR_DOUBLETAP:
                tp_tap_dragging_or_doubletap_handle_event(tp, t, event, time);
                break;
index 6ccb1226e6ca7b4f2f90acceb5ffa212c6f169e8..db642966700ed58956a6b2b5e6555aa5cc221349 100644 (file)
@@ -112,6 +112,8 @@ enum tp_tap_state {
        TAP_STATE_TOUCH_2_RELEASE,
        TAP_STATE_TOUCH_3,
        TAP_STATE_TOUCH_3_HOLD,
+       TAP_STATE_TOUCH_3_RELEASE,
+       TAP_STATE_TOUCH_3_RELEASE_2,
        TAP_STATE_DRAGGING_OR_DOUBLETAP,
        TAP_STATE_DRAGGING_OR_TAP,
        TAP_STATE_DRAGGING,