summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJosé Expósito <jose.exposito89@gmail.com>2021-05-27 19:20:37 +0200
committerPeter Hutterer <peter.hutterer@who-t.net>2021-06-09 01:18:58 +0000
commit9b024c6928686f41aea3d59a04cd80a581bcc857 (patch)
treec568f0818cd8c024753993596e37dd0f3cfb96da /src
parent92827de624c0ee594d0dbe5757c7b6c714d28068 (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.c39
-rw-r--r--src/evdev-mt-touchpad-tap.c13
-rw-r--r--src/evdev-mt-touchpad.c2
-rw-r--r--src/evdev-mt-touchpad.h6
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