From 3b0c194f803ee6588977cdfabc78f28cfb33b9bc Mon Sep 17 00:00:00 2001
From: satrmb
<10471-satrmb_true-email-is-private_contact-via-web@gitlab.freedesktop.org>
Date: Sat, 8 Aug 2020 10:30:31 +0200
Subject: [PATCH] touchpad: count only tapping fingers for clickfinger if
hold-and-tap is on
Unless there are only non-tapping fingers, of course.
For this to work, the tapping state machine needs to hold off on marking all
touches as DEAD on button down. This does not hurt because their state
becomes relevant only when the button has gone up again, which marks them as
DEAD by entering TAP_STATE_DEAD.
Signed-off-by: satrmb <10471-satrmb@users.noreply.gitlab.freedesktop.org>
---
doc/touchpad-tap-state-machine.svg | 2 +-
src/evdev-mt-touchpad-buttons.c | 10 ++++++++++
src/evdev-mt-touchpad-tap.c | 1 -
3 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/doc/touchpad-tap-state-machine.svg b/doc/touchpad-tap-state-machine.svg
index 8429efa4..d02ffa36 100644
--- a/doc/touchpad-tap-state-machine.svg
+++ b/doc/touchpad-tap-state-machine.svg
@@ -1,3 +1,3 @@
-yes no yes no yes no no no no no no no no no no yes no no no yes no yes no yes yes yes no no no no no no no yes yes yes no no yes no no yes yes yes yes yes (this section exists for [n] = 1, [n] = 2, and [n] = 3) (this section exists for [m] = 1, [m] = 2, and [m] = 3), for a total of 9 times due to combination with [n] yes yes yes yes yes yes yes yes yes IDLE first finger down TOUCH_TOUCH TOUCH second finger down TOUCH_TOUCH TOUCH_2 third finger down TOUCH_TOUCH TOUCH_3 TOUCH_2_RELEASE yes either finger up yes remaining finger up any finger up TOUCH_3_RELEASE either finger up TOUCH_3_RELEASE_2 yes remaining finger up TOUCH_IDLE yes TOUCH_IDLE TOUCH_IDLE yes TOUCH_IDLE TOUCH_IDLE palm TOUCH_DEAD either finger palm TOUCH_DEAD yes any finger palm TOUCH_DEAD yes either finger palm TOUCH_DEAD yes remaining finger palm TOUCH_DEAD yes remaining finger palm TOUCH_DEAD 2-finger tap 3-finger tap yes finger up TOUCH_IDLE 1-finger tap fourth finger down IDLE TAPPED yes 2-finger tap palm finger up button [n] press button [n] release DRAGGING_OR_DOUBLETAP yes finger down tap-and-drag timeout timeout move > threshold DRAGGING palm finger up no yes drag-lock enabled? DRAGLOCK_WAIT DRAGLOCK_CONTINUE finger up palm timeout move > threshold drag-lock timeout 1-finger tap yes no non-palm finger count == 0? finger down 1-finger tap timeout timeout hold-and- tap enabled? HOLD 3-finger tap no hold-and- tap enabled? timeout hold-and- tap enabled? 3-finger tap TOUCH_2_HOLD TOUCH_3_HOLD timeout hold-and- tap enabled? timeout yes no hold-and- tap enabled? timeout hold-and- tap enabled? palm finger up TOUCH_DEAD TOUCH_IDLE either finger palm either finger up TOUCH_DEAD TOUCH_IDLE any finger palm any finger up TOUCH_DEAD TOUCH_IDLE TOUCH_TOUCH TOUCH_4_PLUS yes any finger palm yes any finger up TOUCH_IDLE yes TOUCH_DEAD TOUCH_4_PLUS_HOLD timeout hold-and- tap enabled? any finger up TOUCH_IDLE any finger palm TOUCH_DEAD fourth finger down TOUCH_TOUCH TOUCH_4_PLUS_RELEASE yes any finger palm yes any finger up yes TOUCH_DEAD TOUCH_IDLE timeout hold-and- tap enabled? TOUCH_4_PLUS_RELEASE_2 timeout hold-and- tap enabled? yes any finger palm yes any finger up TOUCH_DEAD TOUCH_IDLE TOUCH_4_PLUS_RELEASE_3 timeout hold-and- tap enabled? yes any finger palm yes any finger up yes TOUCH_DEAD TOUCH_IDLE 1-finger tap 2-finger tap 3-finger tap DEAD BUTTON clickpad button release all fingers TOUCH_DEAD no yes non-palm finger count == 0? clickpad button press any finger up TOUCH_IDLE any finger palm move > threshold move > threshold move > threshold move > threshold move > threshold move > threshold move > threshold move > threshold move > threshold hold-and- tap enabled? move > threshold move > threshold hold-and- tap enabled? yes no hold-and- tap enabled? move > threshold hold-and- tap enabled? 3-finger tap move > threshold yes no hold-and- tap enabled? move > threshold yes no hold-and- tap enabled? clickpad button press clickpad button press clickpad button press yes no hold-and- tap enabled? 1-finger tap clickpad button press yes no hold-and- tap enabled? 2-finger tap clickpad button press clickpad button press 3-finger tap yes hold-and- tap enabled? clickpad button press clickpad button press clickpad button press clickpad button press clickpad button press clickpad button press clickpad button press clickpad button press 1-finger tap 3-finger tap button [n] release BUTTON clickpad button release clickpad button press button [n] release clickpad button press clickpad button press clickpad button press clickpad button press clickpad button press button [n] press [n] = 1 [n] = 1 [n] = 2 [n] = 3 no tap-and-drag enabled? move > threshold no non-palm finger count == 1? no non-palm finger count == 0? second finger down second finger down DRAGGING_OR_TAPPED 1-finger tap 2-finger tap [m] = 1 yes [m] = 2 3-finger tap [m] = 3 no yes non-palm finger count == 0? finger up palm [n] = [m] no yes [n] == [m]? no [n] == [m]? button [m] press button [n] release yes clickpad button press no [n] == [m]? button [m] release tap-and-drag timeout move > threshold additional finger down no yes [n] == [m]? button [m] release set tap state to DEAD finger down TOUCH_TOUCH yes hold-and- tap enabled? TOUCH_DEAD no yes no that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? TOUCH_IDLE TOUCH_IDLE TOUCH_IDLE TOUCH_IDLE TOUCH_TOUCH finger count == 0? yes that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? TOUCH_IDLE that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? that finger TOUCH_TOUCH? TOUCH_IDLE TOUCH_IDLE that finger TOUCH_TOUCH? that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? TOUCH_IDLE TOUCH_IDLE no that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? TOUCH_IDLE TOUCH_TOUCH finger count == 1? TOUCH_TOUCH finger count == 2? no TOUCH_TOUCH finger count == 3? thumb yes no drag state == IDLE? yes non-palm finger count == 1? TOUCH_DEAD thumb TOUCH_DEAD no yes no drag state == IDLE? drag state == IDLE? drag state == IDLE? drag state == IDLE? yes no drag state == DRAGLOCK _CONTINUE? 1-finger tap no TOUCH_TOUCH finger count == 3? no hold-and- tap enabled? 3-finger tap no hold-and- tap enabled? no hold-and- tap enabled? no non-palm finger count == 1? no no non-palm finger count == 2? no non-palm finger count == 3? finger down TOUCH_TOUCH no hold-and- tap enabled? 3-finger tap finger down TOUCH_TOUCH hold-and- tap enabled? finger down TOUCH_TOUCH no hold-and- tap enabled? 3-finger tap finger down TOUCH_TOUCH yes hold-and- tap enabled? finger down TOUCH_TOUCH yes hold-and- tap enabled? finger down TOUCH_TOUCH yes hold-and- tap enabled? 1-finger tap 2-finger tap 3-finger tap all fingers except the new one TOUCH_DEAD finger down TOUCH_TOUCH finger down TOUCH_TOUCH all fingers TOUCH_DEAD no Viewer does not support full SVG 1.1
\ No newline at end of file
+yes no yes no yes no no no no no no no no no no yes no no no yes no yes no yes yes yes no no no no no no no yes yes yes no no yes no no yes yes yes yes yes (this section exists for [n] = 1, [n] = 2, and [n] = 3) (this section exists for [m] = 1, [m] = 2, and [m] = 3), for a total of 9 times due to combination with [n] yes yes yes yes yes yes yes yes yes IDLE first finger down TOUCH_TOUCH TOUCH second finger down TOUCH_TOUCH TOUCH_2 third finger down TOUCH_TOUCH TOUCH_3 TOUCH_2_RELEASE yes either finger up yes remaining finger up any finger up TOUCH_3_RELEASE either finger up TOUCH_3_RELEASE_2 yes remaining finger up TOUCH_IDLE yes TOUCH_IDLE TOUCH_IDLE yes TOUCH_IDLE TOUCH_IDLE palm TOUCH_DEAD either finger palm TOUCH_DEAD yes any finger palm TOUCH_DEAD yes either finger palm TOUCH_DEAD yes remaining finger palm TOUCH_DEAD yes remaining finger palm TOUCH_DEAD 2-finger tap 3-finger tap yes finger up TOUCH_IDLE 1-finger tap fourth finger down IDLE TAPPED yes 2-finger tap palm finger up button [n] press button [n] release DRAGGING_OR_DOUBLETAP yes finger down tap-and-drag timeout timeout move > threshold DRAGGING palm finger up no yes drag-lock enabled? DRAGLOCK_WAIT DRAGLOCK_CONTINUE finger up palm timeout move > threshold drag-lock timeout 1-finger tap yes no non-palm finger count == 0? finger down 1-finger tap timeout timeout hold-and- tap enabled? HOLD 3-finger tap no hold-and- tap enabled? timeout hold-and- tap enabled? 3-finger tap TOUCH_2_HOLD TOUCH_3_HOLD timeout hold-and- tap enabled? timeout yes no hold-and- tap enabled? timeout hold-and- tap enabled? palm finger up TOUCH_DEAD TOUCH_IDLE either finger palm either finger up TOUCH_DEAD TOUCH_IDLE any finger palm any finger up TOUCH_DEAD TOUCH_IDLE TOUCH_TOUCH TOUCH_4_PLUS yes any finger palm yes any finger up TOUCH_IDLE yes TOUCH_DEAD TOUCH_4_PLUS_HOLD timeout hold-and- tap enabled? any finger up TOUCH_IDLE any finger palm TOUCH_DEAD fourth finger down TOUCH_TOUCH TOUCH_4_PLUS_RELEASE yes any finger palm yes any finger up yes TOUCH_DEAD TOUCH_IDLE timeout hold-and- tap enabled? TOUCH_4_PLUS_RELEASE_2 timeout hold-and- tap enabled? yes any finger palm yes any finger up TOUCH_DEAD TOUCH_IDLE TOUCH_4_PLUS_RELEASE_3 timeout hold-and- tap enabled? yes any finger palm yes any finger up yes TOUCH_DEAD TOUCH_IDLE 1-finger tap 2-finger tap 3-finger tap DEAD BUTTON clickpad button release all fingers TOUCH_DEAD no yes non-palm finger count == 0? clickpad button press any finger up TOUCH_IDLE any finger palm move > threshold move > threshold move > threshold move > threshold move > threshold move > threshold move > threshold move > threshold move > threshold hold-and- tap enabled? move > threshold move > threshold hold-and- tap enabled? yes no hold-and- tap enabled? move > threshold hold-and- tap enabled? 3-finger tap move > threshold yes no hold-and- tap enabled? move > threshold yes no hold-and- tap enabled? clickpad button press clickpad button press clickpad button press yes no hold-and- tap enabled? 1-finger tap clickpad button press yes no hold-and- tap enabled? 2-finger tap clickpad button press clickpad button press 3-finger tap yes no hold-and- tap enabled? clickpad button press clickpad button press clickpad button press clickpad button press clickpad button press clickpad button press clickpad button press clickpad button press 1-finger tap 3-finger tap button [n] release BUTTON clickpad button release clickpad button press button [n] release clickpad button press clickpad button press clickpad button press clickpad button press clickpad button press button [n] press [n] = 1 [n] = 1 [n] = 2 [n] = 3 no tap-and-drag enabled? move > threshold no non-palm finger count == 1? no non-palm finger count == 0? second finger down second finger down DRAGGING_OR_TAPPED 1-finger tap 2-finger tap [m] = 1 yes [m] = 2 3-finger tap [m] = 3 no yes non-palm finger count == 0? finger up palm [n] = [m] no yes [n] == [m]? no [n] == [m]? button [m] press button [n] release yes clickpad button press no [n] == [m]? button [m] release tap-and-drag timeout move > threshold additional finger down no yes [n] == [m]? button [m] release set tap state to DEAD finger down TOUCH_TOUCH yes hold-and- tap enabled? TOUCH_DEAD no yes no that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? TOUCH_IDLE TOUCH_IDLE TOUCH_IDLE TOUCH_IDLE TOUCH_TOUCH finger count == 0? yes that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? TOUCH_IDLE that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? that finger TOUCH_TOUCH? TOUCH_IDLE TOUCH_IDLE that finger TOUCH_TOUCH? that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? TOUCH_IDLE TOUCH_IDLE no that finger TOUCH_TOUCH? no that finger TOUCH_TOUCH? TOUCH_IDLE TOUCH_TOUCH finger count == 1? TOUCH_TOUCH finger count == 2? no TOUCH_TOUCH finger count == 3? thumb yes no drag state == IDLE? yes non-palm finger count == 1? TOUCH_DEAD thumb TOUCH_DEAD no yes no drag state == IDLE? drag state == IDLE? drag state == IDLE? drag state == IDLE? yes no drag state == DRAGLOCK _CONTINUE? 1-finger tap no TOUCH_TOUCH finger count == 3? no hold-and- tap enabled? 3-finger tap no hold-and- tap enabled? no hold-and- tap enabled? no non-palm finger count == 1? no no non-palm finger count == 2? no non-palm finger count == 3? finger down TOUCH_TOUCH no hold-and- tap enabled? 3-finger tap finger down TOUCH_TOUCH hold-and- tap enabled? finger down TOUCH_TOUCH no hold-and- tap enabled? 3-finger tap finger down TOUCH_TOUCH yes hold-and- tap enabled? finger down TOUCH_TOUCH yes hold-and- tap enabled? finger down TOUCH_TOUCH yes hold-and- tap enabled? 1-finger tap 2-finger tap 3-finger tap all fingers except the new one TOUCH_DEAD finger down TOUCH_TOUCH finger down TOUCH_TOUCH Viewer does not support full SVG 1.1
\ No newline at end of file
diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index 23817da8..2ac889ec 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -1170,11 +1170,13 @@ tp_clickfinger_set_button(struct tp_dispatch *tp)
struct tp_touch *t;
struct tp_touch *first = NULL,
*second = NULL;
+ bool only_taps = tp->tap.hold_tap_enabled;
int32_t button_map[2][3] = {
{ BTN_LEFT, BTN_RIGHT, BTN_MIDDLE },
{ BTN_LEFT, BTN_MIDDLE, BTN_RIGHT },
};
+again:
tp_for_each_touch(tp, t) {
if (t->state != TOUCH_BEGIN && t->state != TOUCH_UPDATE)
continue;
@@ -1185,6 +1187,9 @@ tp_clickfinger_set_button(struct tp_dispatch *tp)
if (t->palm.state != PALM_NONE)
continue;
+ if (only_taps && t->tap.state != TAP_TOUCH_STATE_TOUCH)
+ continue;
+
nfingers++;
if (!first)
@@ -1193,6 +1198,11 @@ tp_clickfinger_set_button(struct tp_dispatch *tp)
second = t;
}
+ if (only_taps && nfingers == 0) {
+ only_taps = false;
+ goto again;
+ }
+
/* Only check for finger distance when there are 2 fingers on the
* touchpad */
if (nfingers != 2)
diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c
index 2977062d..69eecb14 100644
--- a/src/evdev-mt-touchpad-tap.c
+++ b/src/evdev-mt-touchpad-tap.c
@@ -2027,7 +2027,6 @@ tp_tap_handle_event(struct tp_dispatch *tp,
tp_tap_clear_timer(tp);
if ((tp->tap.state == TAP_STATE_IDLE ||
- tp->tap.state == TAP_STATE_BUTTON ||
tp->tap.state == TAP_STATE_DEAD))
tp_tap_kill_all_touches(tp, NULL);
}