diff options
author | José Expósito <jose.exposito89@gmail.com> | 2021-05-27 19:20:37 +0200 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2021-06-09 01:18:58 +0000 |
commit | 9b024c6928686f41aea3d59a04cd80a581bcc857 (patch) | |
tree | c568f0818cd8c024753993596e37dd0f3cfb96da /src | |
parent | 92827de624c0ee594d0dbe5757c7b6c714d28068 (diff) |
gestures: add quick hold implementation
When 1 or 2 fingers are used to hold, use a faster timer to make the
"hold to stop kinetic scrolling" user interaction feel more immediate.
Also handle double tap and tap and drag interations to send only one
hold gesture instead of two.
Holding with 3 or 4 fingers remains the same to try to avoid callers
missusing hold gestures to build their own tap implementation.
Signed-off-by: José Expósito <jose.exposito89@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/evdev-mt-touchpad-gestures.c | 39 | ||||
-rw-r--r-- | src/evdev-mt-touchpad-tap.c | 13 | ||||
-rw-r--r-- | src/evdev-mt-touchpad.c | 2 | ||||
-rw-r--r-- | src/evdev-mt-touchpad.h | 6 |
4 files changed, 56 insertions, 4 deletions
diff --git a/src/evdev-mt-touchpad-gestures.c b/src/evdev-mt-touchpad-gestures.c index 0d5fcedd..4202802e 100644 --- a/src/evdev-mt-touchpad-gestures.c +++ b/src/evdev-mt-touchpad-gestures.c @@ -28,6 +28,7 @@ #include "evdev-mt-touchpad.h" +#define QUICK_GESTURE_HOLD_TIMEOUT ms2us(40) #define DEFAULT_GESTURE_HOLD_TIMEOUT ms2us(180) #define DEFAULT_GESTURE_SWITCH_TIMEOUT ms2us(100) #define DEFAULT_GESTURE_SWIPE_TIMEOUT ms2us(150) @@ -477,12 +478,27 @@ log_gesture_bug(struct tp_dispatch *tp, enum gesture_event event) } static bool +tp_gesture_is_quick_hold(struct tp_dispatch *tp) +{ + /* When 1 or 2 fingers are used to hold, always use a "quick" hold to + * make the hold to stop kinetic scrolling user interaction feel more + * natural. + */ + return (tp->gesture.finger_count == 1) || + (tp->gesture.finger_count == 2); +} + +static bool tp_gesture_use_hold_timer(struct tp_dispatch *tp) { /* When tap is not enabled, always use the timer */ if (!tp->tap.enabled) return true; + /* Always use the timer if it is a quick hold */ + if (tp_gesture_is_quick_hold(tp)) + return true; + /* If the number of fingers on the touchpad exceeds the number of * allowed fingers to tap, use the timer. */ @@ -510,12 +526,17 @@ tp_gesture_use_hold_timer(struct tp_dispatch *tp) static void tp_gesture_set_hold_timer(struct tp_dispatch *tp, uint64_t time) { + uint64_t timeout; + if (!tp->gesture.hold_enabled) return; if (tp_gesture_use_hold_timer(tp)) { - libinput_timer_set(&tp->gesture.hold_timer, - time + DEFAULT_GESTURE_HOLD_TIMEOUT); + timeout = tp_gesture_is_quick_hold(tp) ? + QUICK_GESTURE_HOLD_TIMEOUT : + DEFAULT_GESTURE_HOLD_TIMEOUT; + + libinput_timer_set(&tp->gesture.hold_timer, time + timeout); } } @@ -750,6 +771,10 @@ static void tp_gesture_hold_timeout(uint64_t now, void *data) { struct tp_dispatch *tp = data; + + if (tp_tap_dragging_or_double_tapping(tp) || tp_tap_dragging(tp)) + return; + tp_gesture_handle_event(tp, GESTURE_EVENT_HOLD_TIMEOUT, now); } @@ -759,7 +784,8 @@ tp_gesture_tap_timeout(struct tp_dispatch *tp, uint64_t time) if (!tp->gesture.hold_enabled) return; - tp_gesture_handle_event(tp, GESTURE_EVENT_HOLD_TIMEOUT, time); + if (!tp_gesture_is_quick_hold(tp)) + tp_gesture_handle_event(tp, GESTURE_EVENT_HOLD_TIMEOUT, time); } static void @@ -1264,6 +1290,13 @@ tp_gesture_cancel(struct tp_dispatch *tp, uint64_t time) } void +tp_gesture_cancel_motion_gestures(struct tp_dispatch *tp, uint64_t time) +{ + if (tp->gesture.started && tp->gesture.state != GESTURE_STATE_HOLD) + tp_gesture_end(tp, time, true); +} + +void tp_gesture_stop(struct tp_dispatch *tp, uint64_t time) { tp_gesture_end(tp, time, false); diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c index cbd51036..7c4349a6 100644 --- a/src/evdev-mt-touchpad-tap.c +++ b/src/evdev-mt-touchpad-tap.c @@ -1656,3 +1656,16 @@ tp_tap_dragging(const struct tp_dispatch *tp) return false; } } + +bool +tp_tap_dragging_or_double_tapping(const struct tp_dispatch *tp) +{ + switch (tp->tap.state) { + case TAP_STATE_1FGTAP_DRAGGING_OR_DOUBLETAP: + case TAP_STATE_2FGTAP_DRAGGING_OR_DOUBLETAP: + case TAP_STATE_3FGTAP_DRAGGING_OR_DOUBLETAP: + return true; + default: + return false; + } +} diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index dbb8fd95..c97452a8 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -1874,7 +1874,7 @@ tp_post_events(struct tp_dispatch *tp, uint64_t time) if (ignore_motion) { tp_edge_scroll_stop_events(tp, time); - tp_gesture_cancel(tp, time); + tp_gesture_cancel_motion_gestures(tp, time); tp_gesture_post_events(tp, time, true); return; } diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index 8286085f..c44c7514 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -669,6 +669,9 @@ tp_tap_resume(struct tp_dispatch *tp, uint64_t time); bool tp_tap_dragging(const struct tp_dispatch *tp); +bool +tp_tap_dragging_or_double_tapping(const struct tp_dispatch *tp); + void tp_edge_scroll_init(struct tp_dispatch *tp, struct evdev_device *device); @@ -704,6 +707,9 @@ void tp_gesture_cancel(struct tp_dispatch *tp, uint64_t time); void +tp_gesture_cancel_motion_gestures(struct tp_dispatch *tp, uint64_t time); + +void tp_gesture_handle_state(struct tp_dispatch *tp, uint64_t time); void |