diff options
author | Jasper van Bourgognie | 2025-04-08 21:13:32 +0200 |
---|---|---|
committer | Jasper van Bourgognie | 2025-04-08 21:17:51 +0200 |
commit | 68e0cf3ad1c9440d85a51bb11c5258591012ac7f (patch) | |
tree | 57e6750a2623137a5cea03556cb7457d9b037751 | |
parent | 3cb50413aca02077765c1e23373bce29415caadc (diff) | |
download | aur-libinput-three-finger-drag.tar.gz |
Update to 1.28.1
-rw-r--r-- | .SRCINFO | 37 | ||||
-rw-r--r-- | 0001-Three-finger-dragging-TFD-state-machine.patch | 1505 | ||||
-rw-r--r-- | 0001-gestures-fix-acceleration-in-3fg-drag.patch | 40 | ||||
-rw-r--r-- | 0002-Cleanup.patch | 987 | ||||
-rw-r--r-- | 0002-enable-3fg-drag-by-default.patch | 25 | ||||
-rw-r--r-- | 0003-TFD-add-debounce-state-for-touch-count-decrease.patch | 205 | ||||
-rw-r--r-- | 0004-Take-hold-gestures-and-clickpad-state-into-account.patch | 149 | ||||
-rw-r--r-- | 0005-Debounce-for-4-fingers-before-drag-starts.patch | 174 | ||||
-rw-r--r-- | 0006-Cancel-hold-gestures-instead-of-finishing-them.patch | 36 | ||||
-rw-r--r-- | 0007-Abort-TFD-within-50-ms-on-detection-of-4-fingers.patch | 402 | ||||
-rw-r--r-- | PKGBUILD | 62 |
11 files changed, 103 insertions, 3519 deletions
@@ -1,41 +1,32 @@ pkgbase = libinput-three-finger-drag pkgdesc = Input device management and event handling library - pkgver = 1.27.1 + pkgver = 1.28.1 pkgrel = 1 - url = https://www.freedesktop.org/wiki/Software/libinput/ + url = https://gitlab.freedesktop.org/libinput/libinput arch = x86_64 - license = custom:X11 + license = MIT checkdepends = python-pytest - makedepends = check - makedepends = git makedepends = gtk4 makedepends = meson makedepends = wayland-protocols + makedepends = check + depends = mtdev depends = libevdev depends = libwacom - depends = mtdev - depends = systemd + depends = systemd-libs + depends = glibc optdepends = gtk4: libinput debug-gui optdepends = python-pyudev: libinput measure optdepends = python-libevdev: libinput measure - provides = libinput=1.27.1 + optdepends = python-yaml: used by various tools + provides = libinput=1.28.1 conflicts = libinput - source = git+https://gitlab.freedesktop.org/libinput/libinput.git?signed#tag=1.27.1 - source = 0001-Three-finger-dragging-TFD-state-machine.patch - source = 0002-Cleanup.patch - source = 0003-TFD-add-debounce-state-for-touch-count-decrease.patch - source = 0004-Take-hold-gestures-and-clickpad-state-into-account.patch - source = 0005-Debounce-for-4-fingers-before-drag-starts.patch - source = 0006-Cancel-hold-gestures-instead-of-finishing-them.patch - source = 0007-Abort-TFD-within-50-ms-on-detection-of-4-fingers.patch + source = git+https://gitlab.freedesktop.org/libinput/libinput.git?signed#tag=1.28.1 + source = 0001-gestures-fix-acceleration-in-3fg-drag.patch + source = 0002-enable-3fg-drag-by-default.patch validpgpkeys = 3C2C43D9447D5938EF4551EBE23B7E70B467F0BF b2sums = SKIP - b2sums = 94fb25e198d9a7d8fa05beb398edc0a384d2062c81ca9dc5131c566b97456461eeb5c277873ccf679456ac62bb5432c85ba21e8c5f24ef12d5aa5f05a8ba32f8 - b2sums = 1e409a1062464942661002aa4fd1f7603e9e03c70dab182e59e9ea66caf63ee09051fbfadcb71e76068f3b0286ed08abcff8d3678c846ad971705db710e4d071 - b2sums = ca5f43ee91c732807c4a155b3f7f1e128afa875122302264eef8d63f784f0723fe64754f2ece7dd46a35774798698184e7fdb3ab04ef33da7d1ec39b7c4a69d8 - b2sums = 89e187b97eb7eb824ef1f65efe0a631663b641a18eadb62ee147dfabea40269311cd2c9e2591648411254a4d665ee41d00357c209d90d10acc7e63e54d6e0c97 - b2sums = d909898f54d516a22c479f8b7ce7a419071172a092311d1d39aade3d430ec95924f30ecead23f94affddbeaf904f12098631b985f98929cd2e44f1c5e9e075b0 - b2sums = fce7d335eed9dce132508d35f04835faedf1a73c3910d6542e7e0e537b3ce5acacdf7fc50ef9975f4815bf224879f9284f884d228abef4297c2b8579d7fa74de - b2sums = f58be0c19ec9afb087078037f12935526c2a275ce8ce37fdc6c1165a64d3fb4fa78c6458c18f0b51b3cfa21f6260ae21603e13c2d854979a2df58176e2965b1b + b2sums = ce6e69d41343dbbcee4757b174cf0fb9db6b2dd665a5b0ec248dbb5e76ac9afa38c599d65dc8e86f78475ec518c366a6358c2181a44e7fa629d28a62cf5db9b3 + b2sums = 3332b93d09da6d1c0150c365257aee1f6be7d4ce961849a312e62113ade3eda3c1b01e916e6482f1023641055af3899cab70dee431ca4b2c61ae5d35d4329918 pkgname = libinput-three-finger-drag diff --git a/0001-Three-finger-dragging-TFD-state-machine.patch b/0001-Three-finger-dragging-TFD-state-machine.patch deleted file mode 100644 index 090ec717deec..000000000000 --- a/0001-Three-finger-dragging-TFD-state-machine.patch +++ /dev/null @@ -1,1505 +0,0 @@ -From bd8bfa7d5cbd37a98ef895038b24455435cd6394 Mon Sep 17 00:00:00 2001 -From: abc def <24701-abcdef@users.noreply.gitlab.freedesktop.org> -Date: Fri, 17 Dec 2021 00:42:50 +0100 -Subject: [PATCH 1/7] Three finger dragging (TFD) state machine - -Including explicit states for 4+ finger gesture disambiguation, -drag-lock timeout, and click/tap to drop. - -Signed-off-by: Temp Name <test@example.com> ---- - meson.build | 1 + - src/evdev-mt-touchpad-gestures.c | 5 +- - src/evdev-mt-touchpad-tap.c | 4 + - src/evdev-mt-touchpad-tfd.c | 1306 ++++++++++++++++++++++++++++++ - src/evdev-mt-touchpad.c | 8 + - src/evdev-mt-touchpad.h | 52 ++ - 6 files changed, 1374 insertions(+), 2 deletions(-) - create mode 100644 src/evdev-mt-touchpad-tfd.c - -diff --git a/meson.build b/meson.build -index e2945611..b7cffab7 100644 ---- a/meson.build -+++ b/meson.build -@@ -364,6 +364,7 @@ src_libinput = src_libfilter + [ - 'src/evdev-middle-button.c', - 'src/evdev-mt-touchpad.c', - 'src/evdev-mt-touchpad-tap.c', -+ 'src/evdev-mt-touchpad-tfd.c', - 'src/evdev-mt-touchpad-thumb.c', - 'src/evdev-mt-touchpad-buttons.c', - 'src/evdev-mt-touchpad-edge-scroll.c', -diff --git a/src/evdev-mt-touchpad-gestures.c b/src/evdev-mt-touchpad-gestures.c -index 107d59d7..83bf0393 100644 ---- a/src/evdev-mt-touchpad-gestures.c -+++ b/src/evdev-mt-touchpad-gestures.c -@@ -1566,7 +1566,7 @@ tp_gesture_post_events(struct tp_dispatch *tp, uint64_t time, - * physical button is down, don't allow gestures unless the button - * is held down by a *thumb*, specifically. - */ -- if (tp_tap_dragging(tp) || -+ if (tp_tap_dragging(tp) || tp_tfd_dragging(tp) || - (tp->buttons.is_clickpad && tp->buttons.state && - tp->thumb.state == THUMB_STATE_FINGER)) { - if (tp->gesture.state != GESTURE_STATE_POINTER_MOTION) { -@@ -1714,7 +1714,8 @@ tp_gesture_update_finger_state(struct tp_dispatch *tp, uint64_t time) - active_touches++; - } - -- if (active_touches != tp->gesture.finger_count) { -+ if (active_touches != tp->gesture.finger_count || -+ (active_touches == 3 && true)) { // tp->tfd.three_finger_dragging_enabled)) { - /* If all fingers are lifted immediately end the gesture */ - if (active_touches == 0) { - tp_gesture_stop(tp, time); -diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c -index 3c76c3d6..c689cdc1 100644 ---- a/src/evdev-mt-touchpad-tap.c -+++ b/src/evdev-mt-touchpad-tap.c -@@ -143,10 +143,14 @@ tp_tap_notify(struct tp_dispatch *tp, - else - tp->tap.buttons_pressed &= ~bit(nfingers); - -+ - evdev_pointer_notify_button(tp->device, - time, - button, - state); -+ -+ if (state != LIBINPUT_BUTTON_STATE_PRESSED) -+ tp_tfd_handle_tap(tp, time); - } - - static void -diff --git a/src/evdev-mt-touchpad-tfd.c b/src/evdev-mt-touchpad-tfd.c -new file mode 100644 -index 00000000..54fca8fe ---- /dev/null -+++ b/src/evdev-mt-touchpad-tfd.c -@@ -0,0 +1,1306 @@ -+/* -+ * Copyright © 2013-2015 Red Hat, Inc. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -+ * DEALINGS IN THE SOFTWARE. -+ */ -+ -+#include "config.h" -+ -+#include <assert.h> -+#include <stdbool.h> -+#include <stdio.h> -+ -+#include "evdev-mt-touchpad.h" -+ -+/* when three fingers are detected, this is how long we wait to see if the user -+actually intends a 3 finger gesture, or is transitioning to e.g. 4 fingers */ -+#define DEFAULT_DRAG3_WAIT_FOR_FINGERS_DURATION ms2us(50) -+/* The interval between three fingers touching and a button press being -+performed, if the fingers remain stationary */ -+#define DEFAULT_DRAG3_INITIAL_DELAY ms2us(350) -+/* The time window during which you can continue a 3 finger drag by reapplying -+three fingers. ~700-800 ms seems ideal. */ -+#define DEFAULT_DRAG3_WAIT_FOR_RESUME_DURATION ms2us(720) -+/* The speed at which the *released* finger needs to travel for the drag to -+continue with a single finger */ -+#define DEFAULT_DRAG3_1F_CONTINUATION_SPEED 40 /* mm/s */ -+ -+enum tfd_event { -+ TFD_EVENT_MOTION, -+ TFD_EVENT_TOUCH_COUNT_INCREASE, -+ TFD_EVENT_TOUCH_COUNT_DECREASE, -+ TFD_EVENT_BUTTON, -+ TFD_EVENT_TAP, -+ TFD_EVENT_TIMEOUT, -+ TFD_EVENT_RESUME_TIMEOUT, -+}; -+ -+/***************************************** -+ * -+ * Look at the state diagram in doc/three-finger-drag-state-machine.svg -+ * (generated with https://www.diagrams.net) -+ * -+ * Any changes in this file must be represented in the diagram. -+ */ -+ -+static inline const char* -+tfd_state_to_str(enum tp_tfd_state state) -+{ -+ switch(state) { -+ CASE_RETURN_STRING(TFD_STATE_IDLE); -+ CASE_RETURN_STRING(TFD_STATE_POSSIBLE_DRAG); -+ CASE_RETURN_STRING(TFD_STATE_DRAG); -+ CASE_RETURN_STRING(TFD_STATE_AWAIT_RESUME); -+ CASE_RETURN_STRING(TFD_STATE_POSSIBLE_RESUME); -+ // CASE_RETURN_STRING(TFD_STATE_3F_DRAG_WAIT1); -+ // CASE_RETURN_STRING(TFD_STATE_3F_DRAG_WAIT2); -+ -+ // CASE_RETURN_STRING(TFD_STATE_DEAD); -+ } -+ return NULL; -+} -+ -+static inline const char* -+tfd_event_to_str(enum tfd_event event) -+{ -+ switch(event) { -+ CASE_RETURN_STRING(TFD_EVENT_MOTION); -+ // CASE_RETURN_STRING(TFD_EVENT_MOTION0); -+ // CASE_RETURN_STRING(TFD_EVENT_MOTION1); -+ // CASE_RETURN_STRING(TFD_EVENT_MOTION2); -+ // CASE_RETURN_STRING(TFD_EVENT_MOTION3); -+ // CASE_RETURN_STRING(TFD_EVENT_MOTION4PLUS); -+ // CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT); -+ CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT_INCREASE); -+ CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT_DECREASE); -+ // CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT0); -+ // CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT1); -+ // CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT2); -+ // CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT3); -+ // CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT4PLUS); -+ CASE_RETURN_STRING(TFD_EVENT_BUTTON); -+ CASE_RETURN_STRING(TFD_EVENT_TAP); -+ CASE_RETURN_STRING(TFD_EVENT_TIMEOUT); -+ CASE_RETURN_STRING(TFD_EVENT_RESUME_TIMEOUT); -+ } -+ return NULL; -+} -+ -+// static inline void -+// log_tfd_bug(struct tp_dispatch *tp, struct tp_touch *t, enum tfd_event event) -+// { -+// evdev_log_bug_libinput(tp->device, -+// "%d: invalid tap event %s in state %s\n", -+// t->index, -+// tfd_event_to_str(event), -+// tfd_state_to_str(tp->tfd.state)); -+ -+// } -+ -+static void -+tp_tfd_notify(struct tp_dispatch *tp, -+ uint64_t time, -+ int nfingers, -+ enum libinput_button_state state) -+{ -+ int32_t button; -+ int32_t button_map[2][3] = { -+ { BTN_LEFT, BTN_RIGHT, BTN_MIDDLE }, -+ { BTN_LEFT, BTN_MIDDLE, BTN_RIGHT }, -+ }; -+ -+ assert(tp->tap.map < ARRAY_LENGTH(button_map)); -+ -+ if (nfingers < 1 || nfingers > 3) -+ return; -+ -+ button = button_map[tp->tap.map][nfingers - 1]; -+ -+ if (state == LIBINPUT_BUTTON_STATE_PRESSED) { -+ assert(!(tp->tfd.buttons_pressed & (1 << nfingers))); -+ tp->tfd.buttons_pressed |= (1 << nfingers); -+ } -+ else { -+ assert(tp->tfd.buttons_pressed & (1 << nfingers)); -+ tp->tfd.buttons_pressed &= ~(1 << nfingers); -+ } -+ -+ evdev_pointer_notify_button(tp->device, -+ time, -+ button, -+ state); -+} -+ -+// static void -+// tp_tfd_set_timer(struct tp_dispatch *tp, uint64_t time) -+// { -+// libinput_timer_set(&tp->tfd.timer, time + DEFAULT_TAP_TIMEOUT_PERIOD); -+// } -+ -+// static void -+// tp_tfd_set_drag_timer(struct tp_dispatch *tp, uint64_t time, -+// int nfingers_tapped) -+// { -+// libinput_timer_set(&tp->tfd.timer, -+// time + DEFAULT_DRAG_TIMEOUT_PERIOD_BASE + -+// (nfingers_tapped * -+// DEFAULT_DRAG_TIMEOUT_PERIOD_PERFINGER)); -+// } -+ -+static void -+tp_tfd_set_3f_drag_initial_delay_timer(struct tp_dispatch *tp, uint64_t time)//, -+ // uint64_t duration) -+{ -+ // libinput_timer_set(&tp->tfd.timer, time + duration); -+ libinput_timer_set(&tp->tfd.timer, time + DEFAULT_DRAG3_INITIAL_DELAY); -+} -+ -+static void -+tp_tfd_set_more_fingers_timer(struct tp_dispatch *tp, uint64_t time)//, -+ // uint64_t duration) -+{ -+ // libinput_timer_set(&tp->tfd.timer, time + duration); -+ libinput_timer_set(&tp->tfd.timer, time + DEFAULT_DRAG3_WAIT_FOR_FINGERS_DURATION); -+} -+ -+static void -+tp_tfd_set_3f_drag_wait_timer(struct tp_dispatch *tp, uint64_t time) -+{ -+ libinput_timer_set(&tp->tfd.resume_timer, time + DEFAULT_DRAG3_WAIT_FOR_RESUME_DURATION); -+} -+ -+ -+// static void -+// tp_tfd_set_draglock_timer(struct tp_dispatch *tp, uint64_t time) -+// { -+// libinput_timer_set(&tp->tfd.timer, -+// time + DEFAULT_DRAGLOCK_TIMEOUT_PERIOD); -+// } -+ -+static void -+tp_tfd_clear_timer(struct tp_dispatch *tp) -+{ -+ libinput_timer_cancel(&tp->tfd.timer); -+} -+ -+static void -+tp_tfd_clear_resume_timer(struct tp_dispatch *tp) -+{ -+ libinput_timer_cancel(&tp->tfd.resume_timer); -+} -+ -+// static void -+// tp_tfd_move_to_dead(struct tp_dispatch *tp, struct tp_touch *t) -+// { -+// tp->tfd.state = TFD_STATE_DEAD; -+// t->tfd.state = TAP_TOUCH_STATE_DEAD; -+// tp_tfd_clear_timer(tp); -+// } -+ -+bool -+tp_touch_active_for_tfd(const struct tp_dispatch *tp, const struct tp_touch *t) -+{ -+ return (t->state == TOUCH_BEGIN || t->state == TOUCH_UPDATE) && -+ t->palm.state == PALM_NONE; //&& -+ // !t->pinned.is_pinned && -+ // !tp_thumb_ignored_for_gesture(tp, t) && -+ -+ // not sure what the reason is for these -+ // tp_button_touch_active(tp, t) && -+ // tp_edge_scroll_touch_active(tp, t); -+} -+ -+ -+static struct device_coords -+tp_get_aggregate_touches_coords(const struct tp_dispatch *tp, bool average) -+{ -+ struct tp_touch *t; -+ unsigned int i, nactive = 0; -+ struct device_coords total = {0, 0}; -+ -+ for (i = 0; i < tp->num_slots; i++) { -+ t = &tp->touches[i]; -+ -+ if (!tp_touch_active_for_tfd(tp, t)) -+ continue; -+ -+ nactive++; -+ -+ if (t->dirty) { -+ total.x += t->point.x; -+ total.y += t->point.y; -+ } -+ } -+ -+ if (!average || nactive == 0) -+ return total; -+ -+ total.x /= nactive; -+ total.y /= nactive; -+ -+ return total; -+} -+ -+ -+ -+//-comments = questions -+/*-comments = explanations, intents, ToDos... */ -+ -+/* TODO [done -- at the right place?]: disable 3 finger gestures */ -+ -+static void -+tp_tfd_pin_fingers(struct tp_dispatch *tp) -+{ -+ tp->tfd.cursor_pinned = true; -+ tp->tfd.pinned_point = tp_get_aggregate_touches_coords(tp, true); -+ // struct tp_touch *t; -+ // tp_for_each_touch(tp, t) { -+ // tp_tfd_pin_finger(tp, t); -+ // } -+} -+ -+static void -+tp_tfd_unpin_fingers(struct tp_dispatch *tp) -+{ -+ tp->tfd.cursor_pinned = false; -+ // struct tp_touch *t; -+ // tp_for_each_touch(tp, t) { -+ // t->pinned.is_pinned = false; -+ // } -+} -+ -+static bool -+tp_tfd_should_be_unpinned(const struct tp_dispatch *tp, struct tp_touch *t) -+{ -+ struct phys_coords mm; -+ struct device_coords delta; -+ -+ if (!tp->tfd.cursor_pinned) -+ return true; -+ -+ // unsure why there was a call to abs() here -+ // delta.x = abs(t->point.x - t->pinned.center.x); -+ // delta.y = abs(t->point.y - t->pinned.center.y); -+ -+ delta = tp_get_aggregate_touches_coords(tp, true); -+ delta.x = delta.x - tp->tfd.pinned_point.x; -+ delta.y = delta.y - tp->tfd.pinned_point.y; -+ -+ mm = evdev_device_unit_delta_to_mm(tp->device, &delta); -+ -+ /* 2.0 mm movement -> unpin */ -+ return (hypot(mm.x, mm.y) >= 2.0); -+} -+ -+static void -+tp_tfd_idle_handle_event(struct tp_dispatch *tp, -+ struct tp_touch *t, -+ enum tfd_event event, uint64_t time, int nfingers_down) -+{ -+ switch (event) { -+ case TFD_EVENT_TOUCH_COUNT_INCREASE: -+ case TFD_EVENT_TOUCH_COUNT_DECREASE: -+ if (nfingers_down == 3) { -+ tp->tfd.state = TFD_STATE_POSSIBLE_DRAG; -+ tp_tfd_set_3f_drag_initial_delay_timer(tp, time); -+ } -+ break; -+ case TFD_EVENT_MOTION: -+ break; -+ case TFD_EVENT_RESUME_TIMEOUT: -+ case TFD_EVENT_TIMEOUT: -+ break; // bug -+ case TFD_EVENT_TAP: -+ case TFD_EVENT_BUTTON: -+ break; -+ } -+} -+ -+/* We don't have the primary button pressed in this state; the -+press is delayed since the fingers have remained stationary */ -+static void -+tp_tfd_possible_drag_handle_event(struct tp_dispatch *tp, -+ struct tp_touch *t, -+ enum tfd_event event, uint64_t time, int nfingers_down) -+{ -+ switch (event) { -+ case TFD_EVENT_TOUCH_COUNT_INCREASE: -+ case TFD_EVENT_TOUCH_COUNT_DECREASE: -+ switch (nfingers_down) { -+ case 3: -+ break; // bug -+ default: -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_timer(tp); -+ break; -+ } -+ break; -+ case TFD_EVENT_MOTION: -+ switch (nfingers_down) { -+ default: -+ break; // bug -+ case 3: -+ /* perform a press since it hasn't already been done by the timer */ -+ tp->tfd.state = TFD_STATE_DRAG; -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED); -+ tp_tfd_clear_timer(tp); -+ } -+ break; -+ case TFD_EVENT_RESUME_TIMEOUT: -+ break; -+ case TFD_EVENT_TIMEOUT: -+ /* we've not moved our three fingers so we perform the press after the -+ initial delay */ -+ tp->tfd.state = TFD_STATE_DRAG; -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED); -+ break; -+ case TFD_EVENT_TAP: -+ case TFD_EVENT_BUTTON: -+ // TODO: undecided -+ //tp->tfd.state = TFD_STATE_IDLE; -+ //tp_tfd_clear_timer(tp); -+ break; -+ } -+} -+ -+ -+/* not sure nfingers_down is suitable here since 3f dragging only has a lower -+bound for number of touches in order to exit the 3f drag mode -- no upper bound -+*/ -+static void -+tp_tfd_drag_handle_event(struct tp_dispatch *tp, -+ struct tp_touch *t, -+ enum tfd_event event, uint64_t time, -+ int nfingers_down) -+{ -+ switch (event) { -+ // case TFD_EVENT_TOUCH_COUNT: -+ case TFD_EVENT_TOUCH_COUNT_INCREASE: -+ case TFD_EVENT_TOUCH_COUNT_DECREASE: -+ switch (nfingers_down) { -+ case 0: -+ case 1: -+ tp_tfd_pin_fingers(tp); -+ /* removing all, or all but one, fingers gives you ~0.7 seconds to -+ place three fingers back on the touchpad before the drag ends */ -+ tp_tfd_set_3f_drag_wait_timer(tp, time); -+ tp->tfd.state = TFD_STATE_AWAIT_RESUME; -+ -+ // tp_tfd_pin_fingers(tp); -+ // tp_tfd_set_3f_drag_wait_timer(tp, time); -+ // tp_tfd_set_more_fingers_timer(tp, time); -+ // tp->tfd.state = TFD_STATE_POSSIBLE_RESUME; -+ -+ break; -+ default: -+ break; -+ } -+ break; -+ case TFD_EVENT_MOTION: -+ /* TODO: Future improvement: When one finger moves considerably -+ faster than the others, don't average their deltas for cursor -+ position updates -- use the fastest finger only */ -+ break; -+ case TFD_EVENT_RESUME_TIMEOUT: -+ case TFD_EVENT_TIMEOUT: -+ // log bug -+ break; -+ case TFD_EVENT_TAP: -+ break; -+ case TFD_EVENT_BUTTON: -+ tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_resume_timer(tp); -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ break; -+ } -+} -+ -+ -+ -+ -+ -+ -+/* Drag-lock; After leaving 3 finger dragging there's a small time window where you can -+resume the drag with 3 fingers. */ -+static void -+tp_tfd_await_resume_handle_event(struct tp_dispatch *tp, -+ struct tp_touch *t, -+ enum tfd_event event, uint64_t time, -+ int nfingers_down) -+{ -+ switch (event) { -+ /* we enter this state with 1 or 0 fingers */ -+ case TFD_EVENT_TOUCH_COUNT_DECREASE: -+ /* decreasing the amount of fingers does not concern us in this state -+ as long as an increase to > 3 invariably moves to another state */ -+ break; -+ case TFD_EVENT_TOUCH_COUNT_INCREASE: -+ switch (nfingers_down) { -+ case 0: -+ break; // bug -+ case 1: -+ case 2: -+ // tp_tfd_pin_fingers(tp); -+ // tp_tfd_set_more_fingers_timer(tp, time); -+ // tp->tfd.state = TFD_STATE_POSSIBLE_RESUME; -+ // break; -+ case 3: -+ /* Exactly three fingers are required to resume dragging, in order to -+ enable instant scroll and cursor control. */ -+ // tp->tfd.state = TFD_STATE_POSSIBLE_RESUME; -+ // tp_tfd_set_timer_wait_for_fingers(tp); -+ -+ // tp_tfd_unpin_fingers(tp); -+ // tp_tfd_clear_resume_timer(tp); -+ -+ tp_tfd_pin_fingers(tp); -+ tp_tfd_set_more_fingers_timer(tp, time); -+ -+ // /* when 3 fingers are confirmed, immediately reset drag-lock timeout so -+ // that 3f drags that are shorter than more_fingers_timer will actually -+ // prevents drag-lock from timing out */ -+ // tp_tfd_set_3f_drag_wait_timer(tp, time); -+ // tp_tfd_clear_resume_timer(tp); -+ -+ /* time to disambiguate from a 4 finger gesture */ -+ tp->tfd.state = TFD_STATE_POSSIBLE_RESUME; -+ -+ break; -+ default: -+ // TODO: undecided, but this behavior shouldn't be an issue -+ tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_resume_timer(tp); -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ break; -+ } -+ break; -+ case TFD_EVENT_MOTION: -+ /* Zero, one, or two fingers can be touching. */ -+ switch (nfingers_down) { -+ case 3: -+ break; // bug -+ default: // bug, currently -+ // // TODO: undecided -+ // tp_tfd_unpin_fingers(tp); -+ // tp->tfd.state = TFD_STATE_IDLE; -+ // tp_tfd_clear_resume_timer(tp); -+ // tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ // break; -+ case 1: -+ case 2: -+ if (tp_tfd_should_be_unpinned(tp, t)) { -+ tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_resume_timer(tp); -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ } -+ break; -+ } -+ break; -+ case TFD_EVENT_RESUME_TIMEOUT: -+ /* the drag was not resumed */ -+ tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ break; -+ case TFD_EVENT_TIMEOUT: -+ break; // bug -+ case TFD_EVENT_TAP: -+ case TFD_EVENT_BUTTON: -+ tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_resume_timer(tp); -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ break; -+ } -+} -+ -+/* Waiting for more fingers. Fingers have been detected, but it might be -+a transitory phase towards 2, 4 or more fingers, which should not resume the -+drag. */ -+static void -+tp_tfd_possible_resume_handle_event(struct tp_dispatch *tp, -+ struct tp_touch *t, -+ enum tfd_event event, uint64_t time, -+ int nfingers_down) -+{ -+ switch (event) { -+ case TFD_EVENT_TOUCH_COUNT_INCREASE: -+ // bool did_transition_from_three_fingers = tp->tfd.finger_count == 3; -+ switch (nfingers_down) { -+ case 0: -+ case 1: -+ case 2: -+ // assert(false); -+ // tp_tfd_pin_fingers(tp); -+ // if (did_transition_from_three_fingers) -+ // tp_tfd_set_3f_drag_wait_timer(tp, time); -+ break; -+ case 3: -+ // assert(false); -+ // tp_tfd_pin_fingers(tp); -+ // /* when 3 fingers are confirmed, immediately reset drag-lock timeout so -+ // that 3f drags that are shorter than more_fingers_timer will actually -+ // prevent drag-lock from timing out */ -+ // // TODO: this is wrong. should be set when transitioning from 3 -+ // tp_tfd_set_3f_drag_wait_timer(tp, time); -+ // tp_tfd_clear_resume_timer(tp); -+ break; -+ default: -+ tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_resume_timer(tp); -+ tp_tfd_clear_timer(tp); -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ break; -+ } -+ break; -+ case TFD_EVENT_MOTION: -+ switch (nfingers_down) { -+ case 0: -+ case 1: -+ case 2: -+ // assert(false); -+ break; -+ case 3: -+ tp_tfd_unpin_fingers(tp); -+ tp_tfd_clear_resume_timer(tp); -+ tp_tfd_clear_timer(tp); -+ tp->tfd.state = TFD_STATE_DRAG; -+ break; -+ default: -+ /* should have left the state already */ -+ // TODO: undecided -+ // tp_tfd_unpin_fingers(tp); -+ // tp->tfd.state = TFD_STATE_IDLE; -+ // tp_tfd_clear_resume_timer(tp); -+ // tp_tfd_clear_timer(tp); -+ // tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ break; -+ } -+ break; -+ case TFD_EVENT_RESUME_TIMEOUT: -+ /* immediately evaluate whether to resume. TODO: unwise? */ -+ switch (nfingers_down) { -+ case 3: -+ tp_tfd_unpin_fingers(tp); -+ tp_tfd_clear_timer(tp); -+ tp->tfd.state = TFD_STATE_DRAG; -+ break; -+ default: -+ tp_tfd_unpin_fingers(tp); -+ tp_tfd_clear_timer(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ break; -+ } -+ break; -+ case TFD_EVENT_TOUCH_COUNT_DECREASE: -+ /* a decrease forces immediate evaluation as if the timer had fired */ -+ tp_tfd_clear_timer(tp); -+ /* fallthrough */ -+ case TFD_EVENT_TIMEOUT: -+ /* time to check whether we have 3 fingers touching */ -+ switch (nfingers_down) { -+ case 0: -+ case 1: -+ case 2: -+ // tp_tfd_pin_fingers(tp); -+ // tp_tfd_set_3f_drag_wait_timer(tp, time); -+ tp->tfd.state = TFD_STATE_AWAIT_RESUME; -+ break; -+ case 3: -+ tp_tfd_unpin_fingers(tp); -+ tp_tfd_clear_resume_timer(tp); -+ tp->tfd.state = TFD_STATE_DRAG; -+ break; -+ default: -+ tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_resume_timer(tp); -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ break; -+ } -+ break; -+ case TFD_EVENT_TAP: -+ case TFD_EVENT_BUTTON: -+ tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_resume_timer(tp); -+ tp_tfd_clear_timer(tp); -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ break; -+ } -+} -+ -+ -+ -+ -+ -+ -+// It's too easy to trigger 3fd while scrolling and a third finger -+// touches momentarily. */ -+ -+ -+static void -+tp_tfd_handle_event(struct tp_dispatch *tp, -+ struct tp_touch *t, -+ enum tfd_event event, -+ uint64_t time, -+ int nfingers_down) -+{ -+ enum tp_tfd_state previous_state; -+ // int nfingers_down = tp->tfd.finger_count; -+ previous_state = tp->tfd.state; -+ -+ assert(nfingers_down >= 0); -+ // assert(nfingers_down < 6); // TODO: temp, remove -+ -+ switch (event) { -+ case TFD_EVENT_MOTION: -+ case TFD_EVENT_TOUCH_COUNT_INCREASE: -+ assert(nfingers_down > 0); -+ break; -+ case TFD_EVENT_TOUCH_COUNT_DECREASE: -+ // assert(nfingers_down < 5); -+ break; -+ default: -+ break; -+ } -+ -+ switch(tp->tfd.state) { -+ case TFD_STATE_IDLE: -+ tp_tfd_idle_handle_event(tp, t, event, time, nfingers_down); -+ break; -+ -+ case TFD_STATE_POSSIBLE_DRAG: -+ tp_tfd_possible_drag_handle_event(tp, t, event, time, nfingers_down); -+ break; -+ -+ case TFD_STATE_DRAG: -+ tp_tfd_drag_handle_event(tp, t, event, time, nfingers_down); -+ break; -+ -+ case TFD_STATE_AWAIT_RESUME: -+ tp_tfd_await_resume_handle_event(tp, t, event, time, nfingers_down); -+ break; -+ -+ case TFD_STATE_POSSIBLE_RESUME: -+ tp_tfd_possible_resume_handle_event(tp, t, event, time, nfingers_down); -+ break; -+ } -+ -+ if (previous_state != tp->tfd.state) -+ evdev_log_debug(tp->device, -+ "tfd: touch %d (%s), tfd state %s → %s → %s\n", -+ t ? (int)t->index : -1, -+ t ? touch_state_to_str(t->state) : "", -+ tfd_state_to_str(previous_state), -+ tfd_event_to_str(event), -+ tfd_state_to_str(tp->tfd.state)); -+} -+ -+/* TODO: too arbitrary... need to decide on the semantics of the MOTION event properly */ -+#define DEFAULT_TFD_MOVE_THRESHOLD 0.1 //1.0 //1.3 /* mm */ -+ -+// TODO: how often do clients get motion updates? Isn't that the granularity we -+// want as well? Otherwise we might miss the button press, which will then occur -+// one or more pixels off from the intended position. -+ -+/* reused tap logic */ -+static bool -+tp_tfd_exceeds_motion_threshold(struct tp_dispatch *tp, -+ struct tp_touch *t) -+{ -+ struct phys_coords mm = -+ tp_phys_delta(tp, device_delta(t->point, t->tfd.previous)); -+ -+ /* if we have more fingers down than slots, we know that synaptics -+ * touchpads are likely to give us pointer jumps. -+ * This triggers the movement threshold, making three-finger taps -+ * less reliable (#101435) -+ * -+ * This uses the real nfingers_down, not the one for taps. -+ */ -+ if (tp->device->model_flags & EVDEV_MODEL_SYNAPTICS_SERIAL_TOUCHPAD && -+ (tp->nfingers_down > 2 || tp->old_nfingers_down > 2) && -+ (tp->nfingers_down > tp->num_slots || -+ tp->old_nfingers_down > tp->num_slots)) { -+ return false; -+ } -+ -+ /* Semi-mt devices will give us large movements on finger release, -+ * depending which touch is released. Make sure we ignore any -+ * movement in the same frame as a finger change. -+ */ -+ if (tp->semi_mt && tp->nfingers_down != tp->old_nfingers_down) -+ return false; -+ -+ double threshold = DEFAULT_TFD_MOVE_THRESHOLD; -+ if (tp->tfd.state == TFD_STATE_POSSIBLE_DRAG) { -+ // TODO: have to figure out something better -+ // MOTION events are too decoupled from what's required to actually move -+ // the cursor. TODO: look it up -+ -+ /* the default threshold is too fine-grained for detection of initial -+ button press, but is kind of needed for the unpin distance to be -+ somewhat accurate in the other states a.t.m. */ -+ threshold = 1.3; // same as tap.c -+ } -+ -+ return length_in_mm(mm) > threshold; -+} -+ -+// unused -+static bool -+tp_tfd_enabled(struct tp_dispatch *tp) -+{ -+ return tp->tfd.enabled && !tp->tfd.suspended; -+} -+ -+// unused -+bool -+tp_touch_active_for_tfd_including_edge_palm(const struct tp_dispatch *tp, const struct tp_touch *t) -+{ -+ return (t->state == TOUCH_BEGIN || t->state == TOUCH_UPDATE) && -+ (t->palm.state == PALM_NONE || t->palm.state == PALM_EDGE); //&& -+ // !t->pinned.is_pinned && -+ // !tp_thumb_ignored_for_gesture(tp, t) && -+ -+ // not sure what the reason is for these -+ // tp_button_touch_active(tp, t) && -+ // tp_edge_scroll_touch_active(tp, t); -+} -+ -+void -+tp_tfd_handle_state(struct tp_dispatch *tp, uint64_t time) -+{ -+ unsigned int active_touches = 0; -+ unsigned int active_touches_excluding_edge_palm = 0; -+ // unsigned int active_touches_including_edge_palm = 0; -+ struct tp_touch *t; -+ -+ tp_for_each_touch(tp, t) { -+ if (tp_touch_active_for_tfd(tp, t)) -+ active_touches_excluding_edge_palm++; -+ // if (tp_touch_active_for_tfd_including_edge_palm(tp, t)) -+ // active_touches_including_edge_palm++; -+ } -+ -+ // if (active_touches_excluding_edge_palm >= 2) -+ // active_touches = active_touches_including_edge_palm; -+ // else -+ active_touches = active_touches_excluding_edge_palm; -+ -+ -+ if (active_touches < tp->tfd.finger_count) { -+ tp_tfd_handle_event(tp, t, TFD_EVENT_TOUCH_COUNT_DECREASE, time, active_touches); -+ } -+ else if (active_touches > tp->tfd.finger_count) { -+ tp_tfd_handle_event(tp, t, TFD_EVENT_TOUCH_COUNT_INCREASE, time, active_touches); -+ } -+ -+ // if (active_touches != tp->tfd.finger_count) { -+ // tp->tfd.finger_count = active_touches; -+ -+ // switch (active_touches) { -+ // case 0: -+ // tp_tfd_handle_event(tp, t, TFD_EVENT_TOUCH_COUNT0, time); -+ // break; -+ // case 1: -+ // tp_tfd_handle_event(tp, t, TFD_EVENT_TOUCH_COUNT1, time); -+ // break; -+ // case 2: -+ // tp_tfd_handle_event(tp, t, TFD_EVENT_TOUCH_COUNT2, time); -+ // break; -+ // case 3: -+ // tp_tfd_handle_event(tp, t, TFD_EVENT_TOUCH_COUNT3, time); -+ // break; -+ // default: -+ // tp_tfd_handle_event(tp, t, TFD_EVENT_TOUCH_COUNT4PLUS, time); -+ // break; -+ // } -+ -+ -+ // TODO: consider whether transparent debouncing has any value for TFD. -+ // Probably not; transitions to cursor control and scrolling must never -+ // affect the position for button release, which seems unavoidable with -+ // transparent debouncing -- unless the pin/unpin decisions are also broken -+ // out from event handling... -+ -+ // /* If all fingers are lifted immediately end the gesture */ -+ // if (active_touches == 0) { -+ // tp_gesture_stop(tp, time); -+ // tp->tfd.finger_count = 0; -+ // tp->tfd.finger_count_pending = 0; -+ // /* Immediately switch to new mode to avoid initial latency */ -+ // } else if (!tp->tfd.started) { -+ // tp->tfd.finger_count = active_touches; -+ // tp->tfd.finger_count_pending = 0; -+ // /* If in UNKNOWN or POINTER_MOTION state, go back to -+ // * NONE to re-evaluate leftmost and rightmost touches -+ // */ -+ // if (tp->tfd.state == GESTURE_STATE_UNKNOWN || -+ // tp->tfd.state == GESTURE_STATE_POINTER_MOTION) { -+ // tp_gesture_handle_event(tp, -+ // GESTURE_EVENT_RESET, -+ // time); -+ // } -+ // /* Else debounce finger changes */ -+ // } else if (active_touches != tp->tfd.finger_count_pending) { -+ // tp->tfd.finger_count_pending = active_touches; -+ // libinput_timer_set(&tp->tfd.finger_count_switch_timer, -+ // time + DEFAULT_GESTURE_SWITCH_TIMEOUT); -+ // } -+ // } else { -+ // tp->tfd.finger_count_pending = 0; -+ // } -+ -+ -+ // if (!tp_tfd_enabled(tp)) -+ // return 0; -+ -+ /* Handle queued button pressed events from clickpads. */ -+ if (/* tp->buttons.is_clickpad && */ tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS) -+ tp_tfd_handle_event(tp, NULL, TFD_EVENT_BUTTON, time, active_touches); -+ -+ -+ bool motion_occurred = false; -+ -+ tp_for_each_touch(tp, t) { -+ if (!t->dirty || t->state == TOUCH_NONE) -+ continue; -+ -+ if(!tp_touch_active_for_tfd(tp, t)) -+ continue; -+ -+ if (t->state == TOUCH_HOVERING) -+ continue; -+ -+ if (t->state == TOUCH_BEGIN) { -+ t->tfd.previous = t->point; -+ } -+ else if (t->state == TOUCH_UPDATE) { -+ if (tp_tfd_exceeds_motion_threshold(tp, t)) { // t->tfd.previous.x != t->point.x || t->tfd.previous.y != t->point.y) { -+ motion_occurred = true; -+ } -+ } -+ } -+ -+ if (motion_occurred) { -+ tp_tfd_handle_event(tp, t, TFD_EVENT_MOTION, time, active_touches); -+ // switch (active_touches) { -+ // case 0: -+ // break; // bug? -+ // case 1: -+ // tp_tfd_handle_event(tp, t, TFD_EVENT_MOTION1, time); -+ // break; -+ // case 2: -+ // tp_tfd_handle_event(tp, t, TFD_EVENT_MOTION2, time); -+ // break; -+ // case 3: -+ // tp_tfd_handle_event(tp, t, TFD_EVENT_MOTION3, time); -+ // break; -+ // default: -+ // tp_tfd_handle_event(tp, t, TFD_EVENT_MOTION4PLUS, time); -+ // break; -+ // } -+ } -+ -+ // /** -+ // * In any state where motion exceeding the move threshold would -+ // * move to the next state, filter that motion until we actually -+ // * exceed it. This prevents small motion events while we're waiting -+ // * on a decision if a tap is a tap. -+ // */ -+ // switch (tp->tfd.state) { -+ -+ -+ // case TFD_STATE_3F_DRAG_WAIT0: -+ // case TFD_STATE_3F_DRAG_WAIT1: -+ // case TFD_STATE_3F_DRAG_WAIT2: -+ -+ // filter_motion = 1; -+ // break; -+ -+ // case TFD_STATE_3F_DRAG_BEFORE_PRESS: -+ // case TFD_STATE_3F_DRAG2: -+ // case TFD_STATE_3F_DRAG3: -+ // case TFD_STATE_3F_DRAG4PLUS: -+ // default: -+ // break; -+ -+ // } -+ -+ -+ -+ -+ /* finally, update additional state */ -+ if (motion_occurred) -+ t->tfd.previous = t->point; -+ -+ tp->tfd.finger_count = active_touches; -+ -+ // assert(tp->tfd.nfingers_down <= tp->nfingers_down); -+ // if (tp->nfingers_down == 0) -+ // assert(tp->tfd.nfingers_down == 0); -+ -+ // return filter_motion; -+} -+ -+static void -+tp_tfd_handle_timeout(uint64_t time, void *data) -+{ -+ struct tp_dispatch *tp = data; -+ -+ tp_tfd_handle_event(tp, NULL, TFD_EVENT_TIMEOUT, time, tp->tfd.finger_count); -+} -+ -+static void -+tp_tfd_handle_resume_timeout(uint64_t time, void *data) -+{ -+ struct tp_dispatch *tp = data; -+ -+ tp_tfd_handle_event(tp, NULL, TFD_EVENT_RESUME_TIMEOUT, time, tp->tfd.finger_count); -+} -+ -+/* when a tap occurs the drag can be finished ahead of time if in the waiting state */ -+void -+tp_tfd_handle_tap(struct tp_dispatch *tp, uint64_t time) -+{ -+ switch (tp->tfd.state) { -+ case TFD_STATE_AWAIT_RESUME: -+ case TFD_STATE_POSSIBLE_RESUME: -+ tp_tfd_handle_event(tp, NULL, TFD_EVENT_TAP, time, tp->tfd.finger_count); -+ break; -+ case TFD_STATE_IDLE: -+ case TFD_STATE_POSSIBLE_DRAG: -+ case TFD_STATE_DRAG: -+ break; -+ } -+} -+ -+ -+/* below are some tap.c functions to be adapted if the need arises */ -+ -+ -+// static void -+// tp_tfd_enabled_update(struct tp_dispatch *tp, bool suspended, bool enabled, uint64_t time) -+// { -+// bool was_enabled = tp_tfd_enabled(tp); -+ -+// tp->tfd.suspended = suspended; -+// tp->tfd.enabled = enabled; -+ -+// if (tp_tfd_enabled(tp) == was_enabled) -+// return; -+ -+// if (tp_tfd_enabled(tp)) { -+// struct tp_touch *t; -+ -+// /* On resume, all touches are considered palms */ -+// tp_for_each_touch(tp, t) { -+// if (t->state == TOUCH_NONE) -+// continue; -+ -+// t->tfd.is_palm = true; -+// t->tfd.state = TAP_TOUCH_STATE_DEAD; -+// } -+ -+// tp->tfd.state = TFD_STATE_IDLE; -+// tp->tfd.nfingers_down = 0; -+// } else { -+// tp_release_all_taps(tp, time); -+// } -+// } -+ -+// static int -+// tp_tfd_config_count(struct libinput_device *device) -+// { -+// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; -+// struct tp_dispatch *tp = tp_dispatch(dispatch); -+ -+// return min(tp->ntouches, 3U); /* we only do up to 3 finger tap */ -+// } -+ -+// static enum libinput_config_status -+// tp_tfd_config_set_enabled(struct libinput_device *device, -+// enum libinput_config_tap_state enabled) -+// { -+// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; -+// struct tp_dispatch *tp = tp_dispatch(dispatch); -+ -+// tp_tfd_enabled_update(tp, tp->tfd.suspended, -+// (enabled == LIBINPUT_CONFIG_TAP_ENABLED), -+// libinput_now(device->seat->libinput)); -+ -+// return LIBINPUT_CONFIG_STATUS_SUCCESS; -+// } -+ -+// static enum libinput_config_tap_state -+// tp_tfd_config_is_enabled(struct libinput_device *device) -+// { -+// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; -+// struct tp_dispatch *tp = tp_dispatch(dispatch); -+ -+// return tp->tfd.enabled ? LIBINPUT_CONFIG_TAP_ENABLED : -+// LIBINPUT_CONFIG_TAP_DISABLED; -+// } -+ -+// static enum libinput_config_tap_state -+// tp_tfd_default(struct evdev_device *evdev) -+// { -+// /** -+// * If we don't have a left button we must have tapping enabled by -+// * default. -+// */ -+// if (!libevdev_has_event_code(evdev->evdev, EV_KEY, BTN_LEFT)) -+// return LIBINPUT_CONFIG_TAP_ENABLED; -+ -+// /** -+// * Tapping is disabled by default for two reasons: -+// * * if you don't know that tapping is a thing (or enabled by -+// * default), you get spurious mouse events that make the desktop -+// * feel buggy. -+// * * if you do know what tapping is and you want it, you -+// * usually know where to enable it, or at least you can search for -+// * it. -+// */ -+// return LIBINPUT_CONFIG_TAP_DISABLED; -+// } -+ -+// static enum libinput_config_tap_state -+// tp_tfd_config_get_default(struct libinput_device *device) -+// { -+// struct evdev_device *evdev = evdev_device(device); -+ -+// return tp_tfd_default(evdev); -+// } -+ -+// static enum libinput_config_status -+// tp_tfd_config_set_map(struct libinput_device *device, -+// enum libinput_config_tap_button_map map) -+// { -+// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; -+// struct tp_dispatch *tp = tp_dispatch(dispatch); -+ -+// tp->tfd.want_map = map; -+ -+// tp_tfd_update_map(tp); -+ -+// return LIBINPUT_CONFIG_STATUS_SUCCESS; -+// } -+ -+// static enum libinput_config_tap_button_map -+// tp_tfd_config_get_map(struct libinput_device *device) -+// { -+// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; -+// struct tp_dispatch *tp = tp_dispatch(dispatch); -+ -+// return tp->tfd.want_map; -+// } -+ -+// static enum libinput_config_tap_button_map -+// tp_tfd_config_get_default_map(struct libinput_device *device) -+// { -+// return LIBINPUT_CONFIG_TAP_MAP_LRM; -+// } -+ -+// static enum libinput_config_status -+// tp_tfd_config_set_drag_enabled(struct libinput_device *device, -+// enum libinput_config_drag_state enabled) -+// { -+// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; -+// struct tp_dispatch *tp = tp_dispatch(dispatch); -+ -+// tp->tfd.drag_enabled = enabled; -+ -+// return LIBINPUT_CONFIG_STATUS_SUCCESS; -+// } -+ -+// static enum libinput_config_drag_state -+// tp_tfd_config_get_drag_enabled(struct libinput_device *device) -+// { -+// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; -+// struct tp_dispatch *tp = tp_dispatch(dispatch); -+ -+// return tp->tfd.drag_enabled; -+// } -+ -+// static inline enum libinput_config_drag_state -+// tp_drag_default(struct evdev_device *device) -+// { -+// return LIBINPUT_CONFIG_DRAG_ENABLED; -+// } -+ -+// static enum libinput_config_drag_state -+// tp_tfd_config_get_default_drag_enabled(struct libinput_device *device) -+// { -+// struct evdev_device *evdev = evdev_device(device); -+ -+// return tp_drag_default(evdev); -+// } -+ -+// static enum libinput_config_status -+// tp_tfd_config_set_draglock_enabled(struct libinput_device *device, -+// enum libinput_config_drag_lock_state enabled) -+// { -+// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; -+// struct tp_dispatch *tp = tp_dispatch(dispatch); -+ -+// tp->tfd.drag_lock_enabled = enabled; -+ -+// return LIBINPUT_CONFIG_STATUS_SUCCESS; -+// } -+ -+// static enum libinput_config_drag_lock_state -+// tp_tfd_config_get_draglock_enabled(struct libinput_device *device) -+// { -+// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; -+// struct tp_dispatch *tp = tp_dispatch(dispatch); -+ -+// return tp->tfd.drag_lock_enabled; -+// } -+ -+// static inline enum libinput_config_drag_lock_state -+// tp_drag_lock_default(struct evdev_device *device) -+// { -+// return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED; -+// } -+ -+// static enum libinput_config_drag_lock_state -+// tp_tfd_config_get_default_draglock_enabled(struct libinput_device *device) -+// { -+// struct evdev_device *evdev = evdev_device(device); -+ -+// return tp_drag_lock_default(evdev); -+// } -+ -+void -+tp_init_tfd(struct tp_dispatch *tp) -+{ -+ char timer_name[64]; -+ -+ /* -+ tp->tfd.config.count = tp_tfd_config_count; -+ tp->tfd.config.set_enabled = tp_tfd_config_set_enabled; -+ tp->tfd.config.get_enabled = tp_tfd_config_is_enabled; -+ tp->tfd.config.get_default = tp_tfd_config_get_default; -+ tp->tfd.config.set_map = tp_tfd_config_set_map; -+ tp->tfd.config.get_map = tp_tfd_config_get_map; -+ tp->tfd.config.get_default_map = tp_tfd_config_get_default_map; -+ tp->tfd.config.set_drag_enabled = tp_tfd_config_set_drag_enabled; -+ tp->tfd.config.get_drag_enabled = tp_tfd_config_get_drag_enabled; -+ tp->tfd.config.get_default_drag_enabled = tp_tfd_config_get_default_drag_enabled; -+ tp->tfd.config.set_draglock_enabled = tp_tfd_config_set_draglock_enabled; -+ tp->tfd.config.get_draglock_enabled = tp_tfd_config_get_draglock_enabled; -+ tp->tfd.config.get_default_draglock_enabled = tp_tfd_config_get_default_draglock_enabled; -+ tp->device->base.config.tap = &tp->tfd.config; -+ */ -+ -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp->tfd.enabled = true; //tp_tfd_default(tp->device); -+ tp->tfd.suspended = false; -+ //tp->tfd.map = LIBINPUT_CONFIG_TAP_MAP_LRM; -+ //tp->tfd.want_map = tp->tfd.map; -+ //tp->tfd.drag_enabled = tp_drag_default(tp->device); -+ //tp->tfd.drag_lock_enabled = tp_drag_lock_default(tp->device); -+ tp->tfd.three_finger_dragging_enabled = 1; -+ tp->tfd.finger_count = 0; -+ -+ snprintf(timer_name, -+ sizeof(timer_name), -+ "%s tfd", -+ evdev_device_get_sysname(tp->device)); -+ libinput_timer_init(&tp->tfd.timer, -+ tp_libinput_context(tp), -+ timer_name, -+ tp_tfd_handle_timeout, tp); -+ -+ snprintf(timer_name, -+ sizeof(timer_name), -+ "%s tfd resume", -+ evdev_device_get_sysname(tp->device)); -+ libinput_timer_init(&tp->tfd.resume_timer, -+ tp_libinput_context(tp), -+ timer_name, -+ tp_tfd_handle_resume_timeout, tp); -+} -+ -+// void -+// tp_remove_tap(struct tp_dispatch *tp) -+// { -+// libinput_timer_cancel(&tp->tfd.timer); -+// } -+ -+// void -+// tp_release_all_taps(struct tp_dispatch *tp, uint64_t now) -+// { -+// struct tp_touch *t; -+// int i; -+ -+// for (i = 1; i <= 3; i++) { -+// if (tp->tfd.buttons_pressed & (1 << i)) -+// tp_tfd_notify(tp, now, i, LIBINPUT_BUTTON_STATE_RELEASED); -+// } -+ -+// /* To neutralize all current touches, we make them all palms */ -+// tp_for_each_touch(tp, t) { -+// if (t->state == TOUCH_NONE) -+// continue; -+ -+// if (t->tfd.is_palm) -+// continue; -+ -+// t->tfd.is_palm = true; -+// t->tfd.state = TAP_TOUCH_STATE_DEAD; -+// } -+ -+// tp->tfd.state = TFD_STATE_IDLE; -+// tp->tfd.nfingers_down = 0; -+// } -+ -+// void -+// tp_tfd_suspend(struct tp_dispatch *tp, uint64_t time) -+// { -+// tp_tfd_enabled_update(tp, true, tp->tfd.enabled, time); -+// } -+ -+// void -+// tp_tfd_resume(struct tp_dispatch *tp, uint64_t time) -+// { -+// tp_tfd_enabled_update(tp, false, tp->tfd.enabled, time); -+// } -+ -+bool -+tp_tfd_dragging(const struct tp_dispatch *tp) -+{ -+ switch (tp->tfd.state) { -+ case TFD_STATE_DRAG: -+ case TFD_STATE_AWAIT_RESUME: -+ case TFD_STATE_POSSIBLE_RESUME: -+ return true; -+ default: -+ return false; -+ } -+} -+ -diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c -index d92b9eb0..648a5a3a 100644 ---- a/src/evdev-mt-touchpad.c -+++ b/src/evdev-mt-touchpad.c -@@ -845,6 +845,10 @@ tp_touch_active_for_gesture(const struct tp_dispatch *tp, const struct tp_touch - return (t->state == TOUCH_BEGIN || t->state == TOUCH_UPDATE) && - t->palm.state == PALM_NONE && - !t->pinned.is_pinned && -+ -+ /* let's see if this works */ -+ !tp->tfd.cursor_pinned && -+ - !tp_thumb_ignored_for_gesture(tp, t) && - tp_button_touch_active(tp, t) && - tp_edge_scroll_touch_active(tp, t); -@@ -1862,6 +1866,8 @@ tp_post_events(struct tp_dispatch *tp, uint64_t time) - ignore_motion |= tp_tap_handle_state(tp, time); - ignore_motion |= tp_post_button_events(tp, time); - -+ tp_tfd_handle_state(tp, time); -+ - if (tp->palm.trackpoint_active || tp->dwt.keyboard_active) { - tp_edge_scroll_stop_events(tp, time); - tp_gesture_cancel(tp, time); -@@ -3776,6 +3782,8 @@ tp_init(struct tp_dispatch *tp, - if (!tp_init_accel(tp, LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE)) - return false; - -+ tp_init_tfd(tp); -+ - tp_init_tap(tp); - tp_init_buttons(tp, device); - tp_init_dwt(tp, device); -diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h -index 48d1b113..26593cf7 100644 ---- a/src/evdev-mt-touchpad.h -+++ b/src/evdev-mt-touchpad.h -@@ -134,6 +134,20 @@ enum tp_tap_state { - TAP_STATE_DEAD, /**< finger count exceeded */ - }; - -+ -+enum tp_tfd_state { -+ /* waiting for 3 fingers */ -+ TFD_STATE_IDLE, -+ /* 3 fingers down, possible 4+ f gesture */ -+ TFD_STATE_POSSIBLE_DRAG, -+ /* 3 fingers down and button press has been output */ -+ TFD_STATE_DRAG, -+ /* drag-lock; waiting for drag continuation */ -+ TFD_STATE_AWAIT_RESUME, -+ /* disambiguate between drag continuation and a possible 4+ gesture */ -+ TFD_STATE_POSSIBLE_RESUME, -+}; -+ - enum tp_tap_touch_state { - TAP_TOUCH_STATE_IDLE = 16, /**< not in touch */ - TAP_TOUCH_STATE_TOUCH, /**< touching, may tap */ -@@ -253,6 +267,13 @@ struct tp_touch { - bool is_palm; - } tap; - -+ struct { -+ // enum tp_tap_touch_state state; -+ struct device_coords previous; -+ // bool is_thumb; -+ // bool is_palm; -+ } tfd; -+ - struct { - enum tp_edge_scroll_touch_state edge_state; - uint32_t edge; -@@ -442,6 +463,31 @@ struct tp_dispatch { - unsigned int nfingers_down; /* number of fingers down for tapping (excl. thumb/palm) */ - } tap; - -+ struct { -+ //struct libinput_device_config_tap config; -+ bool enabled; -+ bool suspended; -+ struct libinput_timer timer; -+ struct libinput_timer resume_timer; -+ enum tp_tfd_state state; -+ uint32_t buttons_pressed; -+ uint64_t saved_press_time, -+ saved_release_time; -+ -+ // enum libinput_config_tap_button_map map; -+ //enum libinput_config_tap_button_map want_map; -+ -+ /* true if cursor movement should not be output to clients */ -+ bool cursor_pinned; -+ struct device_coords pinned_point; -+ -+ //bool drag_enabled; -+ //bool drag_lock_enabled; -+ bool three_finger_dragging_enabled; -+ -+ unsigned int finger_count; /* number of fingers down for 3 finger dragging */ -+ } tfd; -+ - struct { - struct libinput_device_config_dwtp config; - bool dwtp_enabled; -@@ -627,6 +673,12 @@ tp_touch_active_for_gesture(const struct tp_dispatch *tp, - int - tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time); - -+void -+tp_tfd_handle_state(struct tp_dispatch *tp, uint64_t time); -+ -+void -+tp_tfd_handle_tap(struct tp_dispatch *tp, uint64_t time); -+ - void - tp_tap_post_process_state(struct tp_dispatch *tp); - --- -2.47.1 - diff --git a/0001-gestures-fix-acceleration-in-3fg-drag.patch b/0001-gestures-fix-acceleration-in-3fg-drag.patch new file mode 100644 index 000000000000..06962bbfa2aa --- /dev/null +++ b/0001-gestures-fix-acceleration-in-3fg-drag.patch @@ -0,0 +1,40 @@ +From 97cd908797bfa10da9e73888fbca9a19357856f2 Mon Sep 17 00:00:00 2001 +From: tokyo4j <hrak1529@gmail.com> +Date: Sat, 5 Apr 2025 11:38:01 +0900 +Subject: [PATCH 1/2] gestures: fix acceleration in 3fg drag + +Before this patch, tp_filter_motion() was called twice in pointer motion +handler during 3fg drag, causing the pointer speed to be much faster +than during 1fg motion when the acceleration profile is adaptive. + +Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1180> +--- + src/evdev-mt-touchpad-gestures.c | 12 ++---------- + 1 file changed, 2 insertions(+), 10 deletions(-) + +diff --git a/src/evdev-mt-touchpad-gestures.c b/src/evdev-mt-touchpad-gestures.c +index c429bd2c..39880eff 100644 +--- a/src/evdev-mt-touchpad-gestures.c ++++ b/src/evdev-mt-touchpad-gestures.c +@@ -1718,16 +1718,8 @@ tp_gesture_handle_state_3fg_drag_start(struct tp_dispatch *tp, uint64_t time) + static void + tp_gesture_handle_state_3fg_drag(struct tp_dispatch *tp, uint64_t time) + { +- if (!(tp->queued & TOUCHPAD_EVENT_MOTION)) +- return; +- +- struct device_float_coords raw = tp_get_average_touches_delta(tp); +- struct normalized_coords delta = tp_filter_motion(tp, &raw, time); +- +- if (!normalized_is_zero(delta) || !device_float_is_zero(raw)) { +- if (tp->queued & TOUCHPAD_EVENT_MOTION) +- tp_gesture_post_pointer_motion(tp, time); +- } ++ if (tp->queued & TOUCHPAD_EVENT_MOTION) ++ tp_gesture_post_pointer_motion(tp, time); + } + + static void +-- +2.47.1 + diff --git a/0002-Cleanup.patch b/0002-Cleanup.patch deleted file mode 100644 index 9ac0c6aa0dc2..000000000000 --- a/0002-Cleanup.patch +++ /dev/null @@ -1,987 +0,0 @@ -From c96a322ad9ceaff0f6d6454b15c1f01810458d23 Mon Sep 17 00:00:00 2001 -From: abc def <24701-abcdef@users.noreply.gitlab.freedesktop.org> -Date: Tue, 4 Jan 2022 19:07:24 +0100 -Subject: [PATCH 2/7] Cleanup - -Signed-off-by: Temp Name <test@example.com> ---- - src/evdev-mt-touchpad-tap.c | 2 +- - src/evdev-mt-touchpad-tfd.c | 615 ++++++------------------------------ - src/evdev-mt-touchpad.h | 6 + - 3 files changed, 108 insertions(+), 515 deletions(-) - -diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c -index c689cdc1..9a0635bd 100644 ---- a/src/evdev-mt-touchpad-tap.c -+++ b/src/evdev-mt-touchpad-tap.c -@@ -148,7 +148,7 @@ tp_tap_notify(struct tp_dispatch *tp, - time, - button, - state); -- -+ - if (state != LIBINPUT_BUTTON_STATE_PRESSED) - tp_tfd_handle_tap(tp, time); - } -diff --git a/src/evdev-mt-touchpad-tfd.c b/src/evdev-mt-touchpad-tfd.c -index 54fca8fe..c12bc27b 100644 ---- a/src/evdev-mt-touchpad-tfd.c -+++ b/src/evdev-mt-touchpad-tfd.c -@@ -1,26 +1,3 @@ --/* -- * Copyright © 2013-2015 Red Hat, Inc. -- * -- * Permission is hereby granted, free of charge, to any person obtaining a -- * copy of this software and associated documentation files (the "Software"), -- * to deal in the Software without restriction, including without limitation -- * the rights to use, copy, modify, merge, publish, distribute, sublicense, -- * and/or sell copies of the Software, and to permit persons to whom the -- * Software is furnished to do so, subject to the following conditions: -- * -- * The above copyright notice and this permission notice (including the next -- * paragraph) shall be included in all copies or substantial portions of the -- * Software. -- * -- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -- * DEALINGS IN THE SOFTWARE. -- */ -- - #include "config.h" - - #include <assert.h> -@@ -53,7 +30,7 @@ enum tfd_event { - }; - - /***************************************** -- * -+ * TODO: provide a diagram - * Look at the state diagram in doc/three-finger-drag-state-machine.svg - * (generated with https://www.diagrams.net) - * -@@ -69,10 +46,6 @@ tfd_state_to_str(enum tp_tfd_state state) - CASE_RETURN_STRING(TFD_STATE_DRAG); - CASE_RETURN_STRING(TFD_STATE_AWAIT_RESUME); - CASE_RETURN_STRING(TFD_STATE_POSSIBLE_RESUME); -- // CASE_RETURN_STRING(TFD_STATE_3F_DRAG_WAIT1); -- // CASE_RETURN_STRING(TFD_STATE_3F_DRAG_WAIT2); -- -- // CASE_RETURN_STRING(TFD_STATE_DEAD); - } - return NULL; - } -@@ -82,19 +55,9 @@ tfd_event_to_str(enum tfd_event event) - { - switch(event) { - CASE_RETURN_STRING(TFD_EVENT_MOTION); -- // CASE_RETURN_STRING(TFD_EVENT_MOTION0); -- // CASE_RETURN_STRING(TFD_EVENT_MOTION1); -- // CASE_RETURN_STRING(TFD_EVENT_MOTION2); -- // CASE_RETURN_STRING(TFD_EVENT_MOTION3); -- // CASE_RETURN_STRING(TFD_EVENT_MOTION4PLUS); - // CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT); - CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT_INCREASE); - CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT_DECREASE); -- // CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT0); -- // CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT1); -- // CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT2); -- // CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT3); -- // CASE_RETURN_STRING(TFD_EVENT_TOUCH_COUNT4PLUS); - CASE_RETURN_STRING(TFD_EVENT_BUTTON); - CASE_RETURN_STRING(TFD_EVENT_TAP); - CASE_RETURN_STRING(TFD_EVENT_TIMEOUT); -@@ -103,16 +66,15 @@ tfd_event_to_str(enum tfd_event event) - return NULL; - } - --// static inline void --// log_tfd_bug(struct tp_dispatch *tp, struct tp_touch *t, enum tfd_event event) --// { --// evdev_log_bug_libinput(tp->device, --// "%d: invalid tap event %s in state %s\n", --// t->index, --// tfd_event_to_str(event), --// tfd_state_to_str(tp->tfd.state)); -- --// } -+static inline void -+log_tfd_bug(struct tp_dispatch *tp, enum tfd_event event, int nfingers_down) -+{ -+ evdev_log_bug_libinput(tp->device, -+ "invalid TFD event %s with %d fingers in state %s\n", -+ tfd_event_to_str(event), -+ nfingers_down, -+ tfd_state_to_str(tp->tfd.state)); -+} - - static void - tp_tfd_notify(struct tp_dispatch *tp, -@@ -148,24 +110,8 @@ tp_tfd_notify(struct tp_dispatch *tp, - state); - } - --// static void --// tp_tfd_set_timer(struct tp_dispatch *tp, uint64_t time) --// { --// libinput_timer_set(&tp->tfd.timer, time + DEFAULT_TAP_TIMEOUT_PERIOD); --// } -- --// static void --// tp_tfd_set_drag_timer(struct tp_dispatch *tp, uint64_t time, --// int nfingers_tapped) --// { --// libinput_timer_set(&tp->tfd.timer, --// time + DEFAULT_DRAG_TIMEOUT_PERIOD_BASE + --// (nfingers_tapped * --// DEFAULT_DRAG_TIMEOUT_PERIOD_PERFINGER)); --// } -- - static void --tp_tfd_set_3f_drag_initial_delay_timer(struct tp_dispatch *tp, uint64_t time)//, -+tp_tfd_set_button_press_delay_timer(struct tp_dispatch *tp, uint64_t time)//, - // uint64_t duration) - { - // libinput_timer_set(&tp->tfd.timer, time + duration); -@@ -173,7 +119,7 @@ tp_tfd_set_3f_drag_initial_delay_timer(struct tp_dispatch *tp, uint64_t time)//, - } - - static void --tp_tfd_set_more_fingers_timer(struct tp_dispatch *tp, uint64_t time)//, -+tp_tfd_set_await_more_fingers_timer(struct tp_dispatch *tp, uint64_t time)//, - // uint64_t duration) - { - // libinput_timer_set(&tp->tfd.timer, time + duration); -@@ -181,19 +127,11 @@ tp_tfd_set_more_fingers_timer(struct tp_dispatch *tp, uint64_t time)//, - } - - static void --tp_tfd_set_3f_drag_wait_timer(struct tp_dispatch *tp, uint64_t time) -+tp_tfd_set_await_resume_timer(struct tp_dispatch *tp, uint64_t time) - { - libinput_timer_set(&tp->tfd.resume_timer, time + DEFAULT_DRAG3_WAIT_FOR_RESUME_DURATION); - } - -- --// static void --// tp_tfd_set_draglock_timer(struct tp_dispatch *tp, uint64_t time) --// { --// libinput_timer_set(&tp->tfd.timer, --// time + DEFAULT_DRAGLOCK_TIMEOUT_PERIOD); --// } -- - static void - tp_tfd_clear_timer(struct tp_dispatch *tp) - { -@@ -206,15 +144,7 @@ tp_tfd_clear_resume_timer(struct tp_dispatch *tp) - libinput_timer_cancel(&tp->tfd.resume_timer); - } - --// static void --// tp_tfd_move_to_dead(struct tp_dispatch *tp, struct tp_touch *t) --// { --// tp->tfd.state = TFD_STATE_DEAD; --// t->tfd.state = TAP_TOUCH_STATE_DEAD; --// tp_tfd_clear_timer(tp); --// } -- --bool -+static bool - tp_touch_active_for_tfd(const struct tp_dispatch *tp, const struct tp_touch *t) - { - return (t->state == TOUCH_BEGIN || t->state == TOUCH_UPDATE) && -@@ -258,32 +188,19 @@ tp_get_aggregate_touches_coords(const struct tp_dispatch *tp, bool average) - return total; - } - -- -- --//-comments = questions --/*-comments = explanations, intents, ToDos... */ -- --/* TODO [done -- at the right place?]: disable 3 finger gestures */ -+/* TODO: disable 3 finger gestures dynamically -- can't have both */ - - static void - tp_tfd_pin_fingers(struct tp_dispatch *tp) - { - tp->tfd.cursor_pinned = true; - tp->tfd.pinned_point = tp_get_aggregate_touches_coords(tp, true); -- // struct tp_touch *t; -- // tp_for_each_touch(tp, t) { -- // tp_tfd_pin_finger(tp, t); -- // } - } - - static void - tp_tfd_unpin_fingers(struct tp_dispatch *tp) - { - tp->tfd.cursor_pinned = false; -- // struct tp_touch *t; -- // tp_for_each_touch(tp, t) { -- // t->pinned.is_pinned = false; -- // } - } - - static bool -@@ -299,6 +216,9 @@ tp_tfd_should_be_unpinned(const struct tp_dispatch *tp, struct tp_touch *t) - // delta.x = abs(t->point.x - t->pinned.center.x); - // delta.y = abs(t->point.y - t->pinned.center.y); - -+ /* TODO: this should correspond to whatever gesture.c does */ -+ /* TODO: can't gesture.c just use the touch with the largest delta so as to -+ allow a single finger to control the cursor at the same speed as all fingers? */ - delta = tp_get_aggregate_touches_coords(tp, true); - delta.x = delta.x - tp->tfd.pinned_point.x; - delta.y = delta.y - tp->tfd.pinned_point.y; -@@ -319,13 +239,14 @@ tp_tfd_idle_handle_event(struct tp_dispatch *tp, - case TFD_EVENT_TOUCH_COUNT_DECREASE: - if (nfingers_down == 3) { - tp->tfd.state = TFD_STATE_POSSIBLE_DRAG; -- tp_tfd_set_3f_drag_initial_delay_timer(tp, time); -+ tp_tfd_set_button_press_delay_timer(tp, time); - } - break; - case TFD_EVENT_MOTION: - break; - case TFD_EVENT_RESUME_TIMEOUT: - case TFD_EVENT_TIMEOUT: -+ log_tfd_bug(tp, event, nfingers_down); - break; // bug - case TFD_EVENT_TAP: - case TFD_EVENT_BUTTON: -@@ -334,7 +255,7 @@ tp_tfd_idle_handle_event(struct tp_dispatch *tp, - } - - /* We don't have the primary button pressed in this state; the --press is delayed since the fingers have remained stationary */ -+press is delayed if the fingers have remained stationary */ - static void - tp_tfd_possible_drag_handle_event(struct tp_dispatch *tp, - struct tp_touch *t, -@@ -344,23 +265,25 @@ tp_tfd_possible_drag_handle_event(struct tp_dispatch *tp, - case TFD_EVENT_TOUCH_COUNT_INCREASE: - case TFD_EVENT_TOUCH_COUNT_DECREASE: - switch (nfingers_down) { -- case 3: -- break; // bug -- default: -- tp->tfd.state = TFD_STATE_IDLE; -- tp_tfd_clear_timer(tp); -- break; -+ case 3: -+ log_tfd_bug(tp, event, nfingers_down); -+ break; // bug -+ default: -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_timer(tp); -+ break; - } - break; - case TFD_EVENT_MOTION: - switch (nfingers_down) { -- default: -- break; // bug -- case 3: -- /* perform a press since it hasn't already been done by the timer */ -- tp->tfd.state = TFD_STATE_DRAG; -- tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED); -- tp_tfd_clear_timer(tp); -+ default: -+ log_tfd_bug(tp, event, nfingers_down); -+ break; // bug -+ case 3: -+ /* perform a press since it hasn't already been done by the timer */ -+ tp->tfd.state = TFD_STATE_DRAG; -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED); -+ tp_tfd_clear_timer(tp); - } - break; - case TFD_EVENT_RESUME_TIMEOUT: -@@ -380,10 +303,6 @@ tp_tfd_possible_drag_handle_event(struct tp_dispatch *tp, - } - } - -- --/* not sure nfingers_down is suitable here since 3f dragging only has a lower --bound for number of touches in order to exit the 3f drag mode -- no upper bound --*/ - static void - tp_tfd_drag_handle_event(struct tp_dispatch *tp, - struct tp_touch *t, -@@ -400,12 +319,12 @@ tp_tfd_drag_handle_event(struct tp_dispatch *tp, - tp_tfd_pin_fingers(tp); - /* removing all, or all but one, fingers gives you ~0.7 seconds to - place three fingers back on the touchpad before the drag ends */ -- tp_tfd_set_3f_drag_wait_timer(tp, time); -+ tp_tfd_set_await_resume_timer(tp, time); - tp->tfd.state = TFD_STATE_AWAIT_RESUME; - - // tp_tfd_pin_fingers(tp); -- // tp_tfd_set_3f_drag_wait_timer(tp, time); -- // tp_tfd_set_more_fingers_timer(tp, time); -+ // tp_tfd_set_await_resume_timer(tp, time); -+ // tp_tfd_set_await_more_fingers_timer(tp, time); - // tp->tfd.state = TFD_STATE_POSSIBLE_RESUME; - - break; -@@ -420,8 +339,8 @@ tp_tfd_drag_handle_event(struct tp_dispatch *tp, - break; - case TFD_EVENT_RESUME_TIMEOUT: - case TFD_EVENT_TIMEOUT: -- // log bug -- break; -+ log_tfd_bug(tp, event, nfingers_down); -+ break; // bug - case TFD_EVENT_TAP: - break; - case TFD_EVENT_BUTTON: -@@ -433,11 +352,6 @@ tp_tfd_drag_handle_event(struct tp_dispatch *tp, - } - } - -- -- -- -- -- - /* Drag-lock; After leaving 3 finger dragging there's a small time window where you can - resume the drag with 3 fingers. */ - static void -@@ -451,15 +365,21 @@ tp_tfd_await_resume_handle_event(struct tp_dispatch *tp, - case TFD_EVENT_TOUCH_COUNT_DECREASE: - /* decreasing the amount of fingers does not concern us in this state - as long as an increase to > 3 invariably moves to another state */ -+ -+ /* TODO: Bug: very quick drags will immediately terminate because of this -+ in combination with breaking out of drag during 1 finger or 2 fingers MOTION. -+ -+ Solution (?): POSSIBLE_BREAK_OUT state concerned with touch count decrease */ - break; - case TFD_EVENT_TOUCH_COUNT_INCREASE: - switch (nfingers_down) { - case 0: -+ log_tfd_bug(tp, event, nfingers_down); - break; // bug - case 1: - case 2: - // tp_tfd_pin_fingers(tp); -- // tp_tfd_set_more_fingers_timer(tp, time); -+ // tp_tfd_set_await_more_fingers_timer(tp, time); - // tp->tfd.state = TFD_STATE_POSSIBLE_RESUME; - // break; - case 3: -@@ -472,12 +392,12 @@ tp_tfd_await_resume_handle_event(struct tp_dispatch *tp, - // tp_tfd_clear_resume_timer(tp); - - tp_tfd_pin_fingers(tp); -- tp_tfd_set_more_fingers_timer(tp, time); -+ tp_tfd_set_await_more_fingers_timer(tp, time); - - // /* when 3 fingers are confirmed, immediately reset drag-lock timeout so - // that 3f drags that are shorter than more_fingers_timer will actually - // prevents drag-lock from timing out */ -- // tp_tfd_set_3f_drag_wait_timer(tp, time); -+ // tp_tfd_set_await_resume_timer(tp, time); - // tp_tfd_clear_resume_timer(tp); - - /* time to disambiguate from a 4 finger gesture */ -@@ -497,8 +417,11 @@ tp_tfd_await_resume_handle_event(struct tp_dispatch *tp, - /* Zero, one, or two fingers can be touching. */ - switch (nfingers_down) { - case 3: -+ log_tfd_bug(tp, event, nfingers_down); - break; // bug - default: // bug, currently -+ log_tfd_bug(tp, event, nfingers_down); -+ break; - // // TODO: undecided - // tp_tfd_unpin_fingers(tp); - // tp->tfd.state = TFD_STATE_IDLE; -@@ -523,6 +446,7 @@ tp_tfd_await_resume_handle_event(struct tp_dispatch *tp, - tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); - break; - case TFD_EVENT_TIMEOUT: -+ log_tfd_bug(tp, event, nfingers_down); - break; // bug - case TFD_EVENT_TAP: - case TFD_EVENT_BUTTON: -@@ -553,7 +477,7 @@ tp_tfd_possible_resume_handle_event(struct tp_dispatch *tp, - // assert(false); - // tp_tfd_pin_fingers(tp); - // if (did_transition_from_three_fingers) -- // tp_tfd_set_3f_drag_wait_timer(tp, time); -+ // tp_tfd_set_await_resume_timer(tp, time); - break; - case 3: - // assert(false); -@@ -562,7 +486,7 @@ tp_tfd_possible_resume_handle_event(struct tp_dispatch *tp, - // that 3f drags that are shorter than more_fingers_timer will actually - // prevent drag-lock from timing out */ - // // TODO: this is wrong. should be set when transitioning from 3 -- // tp_tfd_set_3f_drag_wait_timer(tp, time); -+ // tp_tfd_set_await_resume_timer(tp, time); - // tp_tfd_clear_resume_timer(tp); - break; - default: -@@ -589,6 +513,7 @@ tp_tfd_possible_resume_handle_event(struct tp_dispatch *tp, - break; - default: - /* should have left the state already */ -+ - // TODO: undecided - // tp_tfd_unpin_fingers(tp); - // tp->tfd.state = TFD_STATE_IDLE; -@@ -616,6 +541,8 @@ tp_tfd_possible_resume_handle_event(struct tp_dispatch *tp, - break; - case TFD_EVENT_TOUCH_COUNT_DECREASE: - /* a decrease forces immediate evaluation as if the timer had fired */ -+ /* TODO: might be beneficial with some debouncing on touch count decrease -+ as well, in order to not react too quickly... */ - tp_tfd_clear_timer(tp); - /* fallthrough */ - case TFD_EVENT_TIMEOUT: -@@ -625,7 +552,7 @@ tp_tfd_possible_resume_handle_event(struct tp_dispatch *tp, - case 1: - case 2: - // tp_tfd_pin_fingers(tp); -- // tp_tfd_set_3f_drag_wait_timer(tp, time); -+ // tp_tfd_set_await_resume_timer(tp, time); - tp->tfd.state = TFD_STATE_AWAIT_RESUME; - break; - case 3: -@@ -652,14 +579,8 @@ tp_tfd_possible_resume_handle_event(struct tp_dispatch *tp, - } - } - -- -- -- -- -- --// It's too easy to trigger 3fd while scrolling and a third finger --// touches momentarily. */ -- -+// TODO: It's too easy to trigger 3fd while scrolling and a third finger -+// touches momentarily. */ - - static void - tp_tfd_handle_event(struct tp_dispatch *tp, -@@ -723,10 +644,14 @@ tp_tfd_handle_event(struct tp_dispatch *tp, - #define DEFAULT_TFD_MOVE_THRESHOLD 0.1 //1.0 //1.3 /* mm */ - - // TODO: how often do clients get motion updates? Isn't that the granularity we --// want as well? Otherwise we might miss the button press, which will then occur --// one or more pixels off from the intended position. -+// want as well? Otherwise we might miss cursor motion, and the button press -+// will then occur one or more pixels off from the intended position. -+ -+/* TODO: receive input from gesture.c? */ - - /* reused tap logic */ -+/* TODO: do I really need a threshold? The motion could be handled in event handlers -+directly instead */ - static bool - tp_tfd_exceeds_motion_threshold(struct tp_dispatch *tp, - struct tp_touch *t) -@@ -771,25 +696,25 @@ tp_tfd_exceeds_motion_threshold(struct tp_dispatch *tp, - } - - // unused --static bool --tp_tfd_enabled(struct tp_dispatch *tp) --{ -- return tp->tfd.enabled && !tp->tfd.suspended; --} -+// static bool -+// tp_tfd_enabled(struct tp_dispatch *tp) -+// { -+// return tp->tfd.enabled && !tp->tfd.suspended; -+// } - - // unused --bool --tp_touch_active_for_tfd_including_edge_palm(const struct tp_dispatch *tp, const struct tp_touch *t) --{ -- return (t->state == TOUCH_BEGIN || t->state == TOUCH_UPDATE) && -- (t->palm.state == PALM_NONE || t->palm.state == PALM_EDGE); //&& -- // !t->pinned.is_pinned && -- // !tp_thumb_ignored_for_gesture(tp, t) && -- -- // not sure what the reason is for these -- // tp_button_touch_active(tp, t) && -- // tp_edge_scroll_touch_active(tp, t); --} -+// static bool -+// tp_touch_active_for_tfd_including_edge_palm(const struct tp_dispatch *tp, const struct tp_touch *t) -+// { -+// return (t->state == TOUCH_BEGIN || t->state == TOUCH_UPDATE) && -+// (t->palm.state == PALM_NONE || t->palm.state == PALM_EDGE); //&& -+// // !t->pinned.is_pinned && -+// // !tp_thumb_ignored_for_gesture(tp, t) && -+ -+// // not sure what the reason is for these -+// // tp_button_touch_active(tp, t) && -+// // tp_edge_scroll_touch_active(tp, t); -+// } - - void - tp_tfd_handle_state(struct tp_dispatch *tp, uint64_t time) -@@ -819,63 +744,12 @@ tp_tfd_handle_state(struct tp_dispatch *tp, uint64_t time) - tp_tfd_handle_event(tp, t, TFD_EVENT_TOUCH_COUNT_INCREASE, time, active_touches); - } - -- // if (active_touches != tp->tfd.finger_count) { -- // tp->tfd.finger_count = active_touches; -- -- // switch (active_touches) { -- // case 0: -- // tp_tfd_handle_event(tp, t, TFD_EVENT_TOUCH_COUNT0, time); -- // break; -- // case 1: -- // tp_tfd_handle_event(tp, t, TFD_EVENT_TOUCH_COUNT1, time); -- // break; -- // case 2: -- // tp_tfd_handle_event(tp, t, TFD_EVENT_TOUCH_COUNT2, time); -- // break; -- // case 3: -- // tp_tfd_handle_event(tp, t, TFD_EVENT_TOUCH_COUNT3, time); -- // break; -- // default: -- // tp_tfd_handle_event(tp, t, TFD_EVENT_TOUCH_COUNT4PLUS, time); -- // break; -- // } -- -- - // TODO: consider whether transparent debouncing has any value for TFD. -- // Probably not; transitions to cursor control and scrolling must never -+ // Maybe not; transitions to cursor control and scrolling must never - // affect the position for button release, which seems unavoidable with - // transparent debouncing -- unless the pin/unpin decisions are also broken - // out from event handling... - -- // /* If all fingers are lifted immediately end the gesture */ -- // if (active_touches == 0) { -- // tp_gesture_stop(tp, time); -- // tp->tfd.finger_count = 0; -- // tp->tfd.finger_count_pending = 0; -- // /* Immediately switch to new mode to avoid initial latency */ -- // } else if (!tp->tfd.started) { -- // tp->tfd.finger_count = active_touches; -- // tp->tfd.finger_count_pending = 0; -- // /* If in UNKNOWN or POINTER_MOTION state, go back to -- // * NONE to re-evaluate leftmost and rightmost touches -- // */ -- // if (tp->tfd.state == GESTURE_STATE_UNKNOWN || -- // tp->tfd.state == GESTURE_STATE_POINTER_MOTION) { -- // tp_gesture_handle_event(tp, -- // GESTURE_EVENT_RESET, -- // time); -- // } -- // /* Else debounce finger changes */ -- // } else if (active_touches != tp->tfd.finger_count_pending) { -- // tp->tfd.finger_count_pending = active_touches; -- // libinput_timer_set(&tp->tfd.finger_count_switch_timer, -- // time + DEFAULT_GESTURE_SWITCH_TIMEOUT); -- // } -- // } else { -- // tp->tfd.finger_count_pending = 0; -- // } -- -- - // if (!tp_tfd_enabled(tp)) - // return 0; - -@@ -883,10 +757,10 @@ tp_tfd_handle_state(struct tp_dispatch *tp, uint64_t time) - if (/* tp->buttons.is_clickpad && */ tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS) - tp_tfd_handle_event(tp, NULL, TFD_EVENT_BUTTON, time, active_touches); - -- - bool motion_occurred = false; - - tp_for_each_touch(tp, t) { -+ // TODO: don't know the semantics of `dirty`... - if (!t->dirty || t->state == TOUCH_NONE) - continue; - -@@ -908,52 +782,8 @@ tp_tfd_handle_state(struct tp_dispatch *tp, uint64_t time) - - if (motion_occurred) { - tp_tfd_handle_event(tp, t, TFD_EVENT_MOTION, time, active_touches); -- // switch (active_touches) { -- // case 0: -- // break; // bug? -- // case 1: -- // tp_tfd_handle_event(tp, t, TFD_EVENT_MOTION1, time); -- // break; -- // case 2: -- // tp_tfd_handle_event(tp, t, TFD_EVENT_MOTION2, time); -- // break; -- // case 3: -- // tp_tfd_handle_event(tp, t, TFD_EVENT_MOTION3, time); -- // break; -- // default: -- // tp_tfd_handle_event(tp, t, TFD_EVENT_MOTION4PLUS, time); -- // break; -- // } - } - -- // /** -- // * In any state where motion exceeding the move threshold would -- // * move to the next state, filter that motion until we actually -- // * exceed it. This prevents small motion events while we're waiting -- // * on a decision if a tap is a tap. -- // */ -- // switch (tp->tfd.state) { -- -- -- // case TFD_STATE_3F_DRAG_WAIT0: -- // case TFD_STATE_3F_DRAG_WAIT1: -- // case TFD_STATE_3F_DRAG_WAIT2: -- -- // filter_motion = 1; -- // break; -- -- // case TFD_STATE_3F_DRAG_BEFORE_PRESS: -- // case TFD_STATE_3F_DRAG2: -- // case TFD_STATE_3F_DRAG3: -- // case TFD_STATE_3F_DRAG4PLUS: -- // default: -- // break; -- -- // } -- -- -- -- - /* finally, update additional state */ - if (motion_occurred) - t->tfd.previous = t->point; -@@ -963,8 +793,6 @@ tp_tfd_handle_state(struct tp_dispatch *tp, uint64_t time) - // assert(tp->tfd.nfingers_down <= tp->nfingers_down); - // if (tp->nfingers_down == 0) - // assert(tp->tfd.nfingers_down == 0); -- -- // return filter_motion; - } - - static void -@@ -1000,222 +828,26 @@ tp_tfd_handle_tap(struct tp_dispatch *tp, uint64_t time) - } - - --/* below are some tap.c functions to be adapted if the need arises */ -- -- --// static void --// tp_tfd_enabled_update(struct tp_dispatch *tp, bool suspended, bool enabled, uint64_t time) --// { --// bool was_enabled = tp_tfd_enabled(tp); -- --// tp->tfd.suspended = suspended; --// tp->tfd.enabled = enabled; -- --// if (tp_tfd_enabled(tp) == was_enabled) --// return; -- --// if (tp_tfd_enabled(tp)) { --// struct tp_touch *t; -- --// /* On resume, all touches are considered palms */ --// tp_for_each_touch(tp, t) { --// if (t->state == TOUCH_NONE) --// continue; -- --// t->tfd.is_palm = true; --// t->tfd.state = TAP_TOUCH_STATE_DEAD; --// } -- --// tp->tfd.state = TFD_STATE_IDLE; --// tp->tfd.nfingers_down = 0; --// } else { --// tp_release_all_taps(tp, time); --// } --// } -- --// static int --// tp_tfd_config_count(struct libinput_device *device) --// { --// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; --// struct tp_dispatch *tp = tp_dispatch(dispatch); -- --// return min(tp->ntouches, 3U); /* we only do up to 3 finger tap */ --// } -- --// static enum libinput_config_status --// tp_tfd_config_set_enabled(struct libinput_device *device, --// enum libinput_config_tap_state enabled) --// { --// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; --// struct tp_dispatch *tp = tp_dispatch(dispatch); -- --// tp_tfd_enabled_update(tp, tp->tfd.suspended, --// (enabled == LIBINPUT_CONFIG_TAP_ENABLED), --// libinput_now(device->seat->libinput)); -- --// return LIBINPUT_CONFIG_STATUS_SUCCESS; --// } -- --// static enum libinput_config_tap_state --// tp_tfd_config_is_enabled(struct libinput_device *device) --// { --// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; --// struct tp_dispatch *tp = tp_dispatch(dispatch); -- --// return tp->tfd.enabled ? LIBINPUT_CONFIG_TAP_ENABLED : --// LIBINPUT_CONFIG_TAP_DISABLED; --// } -- --// static enum libinput_config_tap_state --// tp_tfd_default(struct evdev_device *evdev) --// { --// /** --// * If we don't have a left button we must have tapping enabled by --// * default. --// */ --// if (!libevdev_has_event_code(evdev->evdev, EV_KEY, BTN_LEFT)) --// return LIBINPUT_CONFIG_TAP_ENABLED; -- --// /** --// * Tapping is disabled by default for two reasons: --// * * if you don't know that tapping is a thing (or enabled by --// * default), you get spurious mouse events that make the desktop --// * feel buggy. --// * * if you do know what tapping is and you want it, you --// * usually know where to enable it, or at least you can search for --// * it. --// */ --// return LIBINPUT_CONFIG_TAP_DISABLED; --// } -- --// static enum libinput_config_tap_state --// tp_tfd_config_get_default(struct libinput_device *device) --// { --// struct evdev_device *evdev = evdev_device(device); -- --// return tp_tfd_default(evdev); --// } -- --// static enum libinput_config_status --// tp_tfd_config_set_map(struct libinput_device *device, --// enum libinput_config_tap_button_map map) --// { --// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; --// struct tp_dispatch *tp = tp_dispatch(dispatch); -- --// tp->tfd.want_map = map; -- --// tp_tfd_update_map(tp); -- --// return LIBINPUT_CONFIG_STATUS_SUCCESS; --// } -- --// static enum libinput_config_tap_button_map --// tp_tfd_config_get_map(struct libinput_device *device) --// { --// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; --// struct tp_dispatch *tp = tp_dispatch(dispatch); -- --// return tp->tfd.want_map; --// } -- --// static enum libinput_config_tap_button_map --// tp_tfd_config_get_default_map(struct libinput_device *device) --// { --// return LIBINPUT_CONFIG_TAP_MAP_LRM; --// } -- --// static enum libinput_config_status --// tp_tfd_config_set_drag_enabled(struct libinput_device *device, --// enum libinput_config_drag_state enabled) --// { --// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; --// struct tp_dispatch *tp = tp_dispatch(dispatch); -- --// tp->tfd.drag_enabled = enabled; -- --// return LIBINPUT_CONFIG_STATUS_SUCCESS; --// } -- --// static enum libinput_config_drag_state --// tp_tfd_config_get_drag_enabled(struct libinput_device *device) --// { --// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; --// struct tp_dispatch *tp = tp_dispatch(dispatch); -- --// return tp->tfd.drag_enabled; --// } -- --// static inline enum libinput_config_drag_state --// tp_drag_default(struct evdev_device *device) --// { --// return LIBINPUT_CONFIG_DRAG_ENABLED; --// } -- --// static enum libinput_config_drag_state --// tp_tfd_config_get_default_drag_enabled(struct libinput_device *device) --// { --// struct evdev_device *evdev = evdev_device(device); -- --// return tp_drag_default(evdev); --// } -- --// static enum libinput_config_status --// tp_tfd_config_set_draglock_enabled(struct libinput_device *device, --// enum libinput_config_drag_lock_state enabled) --// { --// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; --// struct tp_dispatch *tp = tp_dispatch(dispatch); -- --// tp->tfd.drag_lock_enabled = enabled; -- --// return LIBINPUT_CONFIG_STATUS_SUCCESS; --// } -- --// static enum libinput_config_drag_lock_state --// tp_tfd_config_get_draglock_enabled(struct libinput_device *device) --// { --// struct evdev_dispatch *dispatch = evdev_device(device)->dispatch; --// struct tp_dispatch *tp = tp_dispatch(dispatch); -- --// return tp->tfd.drag_lock_enabled; --// } -- --// static inline enum libinput_config_drag_lock_state --// tp_drag_lock_default(struct evdev_device *device) --// { --// return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED; --// } -- --// static enum libinput_config_drag_lock_state --// tp_tfd_config_get_default_draglock_enabled(struct libinput_device *device) --// { --// struct evdev_device *evdev = evdev_device(device); -- --// return tp_drag_lock_default(evdev); --// } - - void - tp_init_tfd(struct tp_dispatch *tp) - { - char timer_name[64]; - -- /* -- tp->tfd.config.count = tp_tfd_config_count; -- tp->tfd.config.set_enabled = tp_tfd_config_set_enabled; -- tp->tfd.config.get_enabled = tp_tfd_config_is_enabled; -- tp->tfd.config.get_default = tp_tfd_config_get_default; -- tp->tfd.config.set_map = tp_tfd_config_set_map; -- tp->tfd.config.get_map = tp_tfd_config_get_map; -- tp->tfd.config.get_default_map = tp_tfd_config_get_default_map; -- tp->tfd.config.set_drag_enabled = tp_tfd_config_set_drag_enabled; -- tp->tfd.config.get_drag_enabled = tp_tfd_config_get_drag_enabled; -- tp->tfd.config.get_default_drag_enabled = tp_tfd_config_get_default_drag_enabled; -- tp->tfd.config.set_draglock_enabled = tp_tfd_config_set_draglock_enabled; -- tp->tfd.config.get_draglock_enabled = tp_tfd_config_get_draglock_enabled; -- tp->tfd.config.get_default_draglock_enabled = tp_tfd_config_get_default_draglock_enabled; -- tp->device->base.config.tap = &tp->tfd.config; -- */ -+ // tp->tfd.config.count = tp_tfd_config_count; -+ // tp->tfd.config.set_enabled = tp_tfd_config_set_enabled; -+ // tp->tfd.config.get_enabled = tp_tfd_config_is_enabled; -+ // tp->tfd.config.get_default = tp_tfd_config_get_default; -+ // tp->tfd.config.set_map = tp_tfd_config_set_map; -+ // tp->tfd.config.get_map = tp_tfd_config_get_map; -+ // tp->tfd.config.get_default_map = tp_tfd_config_get_default_map; -+ // tp->tfd.config.set_drag_enabled = tp_tfd_config_set_drag_enabled; -+ // tp->tfd.config.get_drag_enabled = tp_tfd_config_get_drag_enabled; -+ // tp->tfd.config.get_default_drag_enabled = tp_tfd_config_get_default_drag_enabled; -+ // tp->tfd.config.set_draglock_enabled = tp_tfd_config_set_draglock_enabled; -+ // tp->tfd.config.get_draglock_enabled = tp_tfd_config_get_draglock_enabled; -+ // tp->tfd.config.get_default_draglock_enabled = tp_tfd_config_get_default_draglock_enabled; -+ // tp->device->base.config.tap = &tp->tfd.config; - - tp->tfd.state = TFD_STATE_IDLE; - tp->tfd.enabled = true; //tp_tfd_default(tp->device); -@@ -1246,51 +878,6 @@ tp_init_tfd(struct tp_dispatch *tp) - tp_tfd_handle_resume_timeout, tp); - } - --// void --// tp_remove_tap(struct tp_dispatch *tp) --// { --// libinput_timer_cancel(&tp->tfd.timer); --// } -- --// void --// tp_release_all_taps(struct tp_dispatch *tp, uint64_t now) --// { --// struct tp_touch *t; --// int i; -- --// for (i = 1; i <= 3; i++) { --// if (tp->tfd.buttons_pressed & (1 << i)) --// tp_tfd_notify(tp, now, i, LIBINPUT_BUTTON_STATE_RELEASED); --// } -- --// /* To neutralize all current touches, we make them all palms */ --// tp_for_each_touch(tp, t) { --// if (t->state == TOUCH_NONE) --// continue; -- --// if (t->tfd.is_palm) --// continue; -- --// t->tfd.is_palm = true; --// t->tfd.state = TAP_TOUCH_STATE_DEAD; --// } -- --// tp->tfd.state = TFD_STATE_IDLE; --// tp->tfd.nfingers_down = 0; --// } -- --// void --// tp_tfd_suspend(struct tp_dispatch *tp, uint64_t time) --// { --// tp_tfd_enabled_update(tp, true, tp->tfd.enabled, time); --// } -- --// void --// tp_tfd_resume(struct tp_dispatch *tp, uint64_t time) --// { --// tp_tfd_enabled_update(tp, false, tp->tfd.enabled, time); --// } -- - bool - tp_tfd_dragging(const struct tp_dispatch *tp) - { -diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h -index 26593cf7..2b820b41 100644 ---- a/src/evdev-mt-touchpad.h -+++ b/src/evdev-mt-touchpad.h -@@ -688,6 +688,9 @@ tp_button_post_process_state(struct tp_dispatch *tp); - void - tp_init_tap(struct tp_dispatch *tp); - -+void -+tp_init_tfd(struct tp_dispatch *tp); -+ - void - tp_remove_tap(struct tp_dispatch *tp); - -@@ -738,6 +741,9 @@ tp_tap_resume(struct tp_dispatch *tp, uint64_t time); - bool - tp_tap_dragging(const struct tp_dispatch *tp); - -+bool -+tp_tfd_dragging(const struct tp_dispatch *tp); -+ - bool - tp_tap_dragging_or_double_tapping(const struct tp_dispatch *tp); - --- -2.47.1 - diff --git a/0002-enable-3fg-drag-by-default.patch b/0002-enable-3fg-drag-by-default.patch new file mode 100644 index 000000000000..6213953a370f --- /dev/null +++ b/0002-enable-3fg-drag-by-default.patch @@ -0,0 +1,25 @@ +From 4852593c91a5dad1a473c374b67e6a7a764f1a30 Mon Sep 17 00:00:00 2001 +From: Jasper van Bourgognie <van.bourgognie@gmail.com> +Date: Tue, 8 Apr 2025 20:51:51 +0200 +Subject: [PATCH 2/2] enable 3fg-drag by default + +--- + src/evdev-mt-touchpad-gestures.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/evdev-mt-touchpad-gestures.c b/src/evdev-mt-touchpad-gestures.c +index 39880eff..a4108d83 100644 +--- a/src/evdev-mt-touchpad-gestures.c ++++ b/src/evdev-mt-touchpad-gestures.c +@@ -2147,7 +2147,7 @@ tp_3fg_drag_get_enabled(struct libinput_device *device) + static enum libinput_config_3fg_drag_state + tp_3fg_drag_default(struct tp_dispatch *tp) + { +- return LIBINPUT_CONFIG_3FG_DRAG_DISABLED; ++ return LIBINPUT_CONFIG_3FG_DRAG_ENABLED_3FG; + } + + static enum libinput_config_3fg_drag_state +-- +2.47.1 + diff --git a/0003-TFD-add-debounce-state-for-touch-count-decrease.patch b/0003-TFD-add-debounce-state-for-touch-count-decrease.patch deleted file mode 100644 index 8ceb64caccc0..000000000000 --- a/0003-TFD-add-debounce-state-for-touch-count-decrease.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 006dff13f1c852c77537aaf19da2245d32c30126 Mon Sep 17 00:00:00 2001 -From: abc def <24701-abcdef@users.noreply.gitlab.freedesktop.org> -Date: Thu, 6 Jan 2022 13:22:42 +0100 -Subject: [PATCH 3/7] TFD: add debounce state for touch count decrease - -Don't allow motion events within a certain interval from a touch count decrease (to 1 finger) to finish the drag. This should make even very quick drags remain in drag-lock instead of being unintentionally finished by the last finger. - -Signed-off-by: Temp Name <test@example.com> ---- - src/evdev-mt-touchpad-tfd.c | 93 ++++++++++++++++++++++++++++++++++--- - src/evdev-mt-touchpad.h | 13 ++++-- - 2 files changed, 96 insertions(+), 10 deletions(-) - -diff --git a/src/evdev-mt-touchpad-tfd.c b/src/evdev-mt-touchpad-tfd.c -index c12bc27b..49c576bd 100644 ---- a/src/evdev-mt-touchpad-tfd.c -+++ b/src/evdev-mt-touchpad-tfd.c -@@ -44,6 +44,7 @@ tfd_state_to_str(enum tp_tfd_state state) - CASE_RETURN_STRING(TFD_STATE_IDLE); - CASE_RETURN_STRING(TFD_STATE_POSSIBLE_DRAG); - CASE_RETURN_STRING(TFD_STATE_DRAG); -+ CASE_RETURN_STRING(TFD_STATE_POSSIBLE_ZERO_FINGERS); - CASE_RETURN_STRING(TFD_STATE_AWAIT_RESUME); - CASE_RETURN_STRING(TFD_STATE_POSSIBLE_RESUME); - } -@@ -275,6 +276,8 @@ tp_tfd_possible_drag_handle_event(struct tp_dispatch *tp, - } - break; - case TFD_EVENT_MOTION: -+ /* this event must ensure it fires upon cursor movement -- alternatively, if -+ impossible, TODO: cursor should be pinned in this state to ensure this */ - switch (nfingers_down) { - default: - log_tfd_bug(tp, event, nfingers_down); -@@ -303,6 +306,12 @@ tp_tfd_possible_drag_handle_event(struct tp_dispatch *tp, - } - } - -+ -+ /* TODO: Future improvement: When one finger moves considerably -+ faster than the others, don't average their deltas for cursor -+ position updates -- use the fastest finger only */ -+ -+ - static void - tp_tfd_drag_handle_event(struct tp_dispatch *tp, - struct tp_touch *t, -@@ -315,10 +324,7 @@ tp_tfd_drag_handle_event(struct tp_dispatch *tp, - case TFD_EVENT_TOUCH_COUNT_DECREASE: - switch (nfingers_down) { - case 0: -- case 1: - tp_tfd_pin_fingers(tp); -- /* removing all, or all but one, fingers gives you ~0.7 seconds to -- place three fingers back on the touchpad before the drag ends */ - tp_tfd_set_await_resume_timer(tp, time); - tp->tfd.state = TFD_STATE_AWAIT_RESUME; - -@@ -327,15 +333,18 @@ tp_tfd_drag_handle_event(struct tp_dispatch *tp, - // tp_tfd_set_await_more_fingers_timer(tp, time); - // tp->tfd.state = TFD_STATE_POSSIBLE_RESUME; - -+ break; -+ case 1: -+ tp_tfd_pin_fingers(tp); -+ tp_tfd_set_await_resume_timer(tp, time); -+ tp_tfd_set_await_more_fingers_timer(tp, time); -+ tp->tfd.state = TFD_STATE_POSSIBLE_ZERO_FINGERS; - break; - default: - break; - } - break; - case TFD_EVENT_MOTION: -- /* TODO: Future improvement: When one finger moves considerably -- faster than the others, don't average their deltas for cursor -- position updates -- use the fastest finger only */ - break; - case TFD_EVENT_RESUME_TIMEOUT: - case TFD_EVENT_TIMEOUT: -@@ -352,6 +361,73 @@ tp_tfd_drag_handle_event(struct tp_dispatch *tp, - } - } - -+ -+/* Waiting for zero fingers. Drag has decreased to 1 finger, but it might be -+a transitory phase towards 0 fingers. Allow a small amount of time for that -+before allowing one finger to break out of the drag in the AWAIT state. Makes it -+harder to end very fast, brief drags. */ -+static void -+tp_tfd_possible_zero_fingers_handle_event(struct tp_dispatch *tp, -+ struct tp_touch *t, -+ enum tfd_event event, uint64_t time, -+ int nfingers_down) -+{ -+ switch (event) { -+ case TFD_EVENT_TOUCH_COUNT_DECREASE: -+ switch (nfingers_down) { -+ case 0: -+ tp_tfd_clear_timer(tp); -+ tp->tfd.state = TFD_STATE_AWAIT_RESUME; -+ break; -+ default: -+ log_tfd_bug(tp, event, nfingers_down); -+ break; -+ } -+ break; -+ case TFD_EVENT_MOTION: -+ break; -+ case TFD_EVENT_RESUME_TIMEOUT: -+ /* this shouldn't have time to happen */ -+ log_tfd_bug(tp, event, nfingers_down); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_timer(tp); -+ tp_tfd_unpin_fingers(tp); -+ break; -+ case TFD_EVENT_TOUCH_COUNT_INCREASE: -+ /* an increase forces immediate evaluation as if the timer had fired */ -+ tp_tfd_clear_timer(tp); -+ /* fallthrough */ -+ case TFD_EVENT_TIMEOUT: -+ /* time to (most probably) transition to the AWAIT state with 0 or 1 fingers */ -+ switch (nfingers_down) { -+ case 0: -+ case 1: -+ case 2: -+ tp->tfd.state = TFD_STATE_AWAIT_RESUME; -+ break; -+ case 3: -+ tp_tfd_set_await_more_fingers_timer(tp, time); -+ tp->tfd.state = TFD_STATE_POSSIBLE_RESUME; -+ break; -+ default: -+ tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_resume_timer(tp); -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ break; -+ } -+ break; -+ case TFD_EVENT_TAP: -+ case TFD_EVENT_BUTTON: -+ tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_resume_timer(tp); -+ tp_tfd_clear_timer(tp); -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ break; -+ } -+} -+ - /* Drag-lock; After leaving 3 finger dragging there's a small time window where you can - resume the drag with 3 fingers. */ - static void -@@ -621,6 +697,10 @@ tp_tfd_handle_event(struct tp_dispatch *tp, - tp_tfd_drag_handle_event(tp, t, event, time, nfingers_down); - break; - -+ case TFD_STATE_POSSIBLE_ZERO_FINGERS: -+ tp_tfd_possible_zero_fingers_handle_event(tp, t, event, time, nfingers_down); -+ break; -+ - case TFD_STATE_AWAIT_RESUME: - tp_tfd_await_resume_handle_event(tp, t, event, time, nfingers_down); - break; -@@ -816,6 +896,7 @@ void - tp_tfd_handle_tap(struct tp_dispatch *tp, uint64_t time) - { - switch (tp->tfd.state) { -+ case TFD_STATE_POSSIBLE_ZERO_FINGERS: - case TFD_STATE_AWAIT_RESUME: - case TFD_STATE_POSSIBLE_RESUME: - tp_tfd_handle_event(tp, NULL, TFD_EVENT_TAP, time, tp->tfd.finger_count); -diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h -index 2b820b41..3e464869 100644 ---- a/src/evdev-mt-touchpad.h -+++ b/src/evdev-mt-touchpad.h -@@ -136,15 +136,20 @@ enum tp_tap_state { - - - enum tp_tfd_state { -+ /* [debounce] = brief states anticipating a further increase/decrease in finger -+ count, preventing unintended drops on account of motion events */ -+ - /* waiting for 3 fingers */ - TFD_STATE_IDLE, -- /* 3 fingers down, possible 4+ f gesture */ -+ /* 3 fingers touching, possible 4+ f gesture */ - TFD_STATE_POSSIBLE_DRAG, -- /* 3 fingers down and button press has been output */ -+ /* 3 fingers touching and button press has been output */ - TFD_STATE_DRAG, -- /* drag-lock; waiting for drag continuation */ -+ /* [debounce] drag-lock; 1 finger touching, possibly going to 0 fingers */ -+ TFD_STATE_POSSIBLE_ZERO_FINGERS, -+ /* drag-lock; waiting for 3 finger drag continuation */ - TFD_STATE_AWAIT_RESUME, -- /* disambiguate between drag continuation and a possible 4+ gesture */ -+ /* [debounce] disambiguate between drag continuation and a possible 4+ gesture */ - TFD_STATE_POSSIBLE_RESUME, - }; - --- -2.47.1 - diff --git a/0004-Take-hold-gestures-and-clickpad-state-into-account.patch b/0004-Take-hold-gestures-and-clickpad-state-into-account.patch deleted file mode 100644 index 7d581ed3069a..000000000000 --- a/0004-Take-hold-gestures-and-clickpad-state-into-account.patch +++ /dev/null @@ -1,149 +0,0 @@ -From a1cce9b4244098ef5f6a1de401bcad7828bea196 Mon Sep 17 00:00:00 2001 -From: abc def <24701-abcdef@users.noreply.gitlab.freedesktop.org> -Date: Thu, 27 Jan 2022 14:50:30 +0100 -Subject: [PATCH 4/7] Take hold gestures and clickpad state into account - -- Avoid entering the drag state if the clickpad is pressed. -- Finish hold gestures and cancel other gestures before entering the drag state. ---- - src/evdev-mt-touchpad-tfd.c | 77 ++++++++++++++++++++++++++++++++++--- - 1 file changed, 71 insertions(+), 6 deletions(-) - -diff --git a/src/evdev-mt-touchpad-tfd.c b/src/evdev-mt-touchpad-tfd.c -index 49c576bd..c1c32862 100644 ---- a/src/evdev-mt-touchpad-tfd.c -+++ b/src/evdev-mt-touchpad-tfd.c -@@ -255,6 +255,28 @@ tp_tfd_idle_handle_event(struct tp_dispatch *tp, - } - } - -+/* finishes hold gestures and cancels other gestures */ -+static void -+tp_tfd_interrupt_gestures(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time) -+{ -+ switch (tp->gesture.state) { -+ case GESTURE_STATE_NONE: -+ case GESTURE_STATE_POINTER_MOTION: -+ break; /* should be harmless enough? */ -+ case GESTURE_STATE_HOLD: -+ case GESTURE_STATE_HOLD_AND_MOTION: -+ /* starting a drag should finish a hold gesture -- not -+ cancel it (if there's any difference?) */ -+ tp_gesture_stop(tp, time); -+ break; -+ default: -+ tp_gesture_cancel(tp, time); -+ break; -+ } -+ /* TODO: sooner or later, calls between state machines will start resulting -+ in infinite recursion... */ -+} -+ - /* We don't have the primary button pressed in this state; the - press is delayed if the fingers have remained stationary */ - static void -@@ -262,6 +284,11 @@ tp_tfd_possible_drag_handle_event(struct tp_dispatch *tp, - struct tp_touch *t, - enum tfd_event event, uint64_t time, int nfingers_down) - { -+ /* it is possible to use 3 fingers with a clickpad to emulate e.g. middle -+ mouse button clicks, and no-one wants a primary click while doing a middle -+ click on a link, for instance */ -+ bool clickpad_pressed = tp->buttons.is_clickpad && tp->buttons.state; -+ - switch (event) { - case TFD_EVENT_TOUCH_COUNT_INCREASE: - case TFD_EVENT_TOUCH_COUNT_DECREASE: -@@ -276,14 +303,22 @@ tp_tfd_possible_drag_handle_event(struct tp_dispatch *tp, - } - break; - case TFD_EVENT_MOTION: -- /* this event must ensure it fires upon cursor movement -- alternatively, if -- impossible, TODO: cursor should be pinned in this state to ensure this */ -+ /* this event must ensure it fires upon cursor movement -+ -+ alternatively: cursor should be pinned in this state to ensure this. -+ But pinning is not acceptable in this state as long as we check clickpad -+ state and exit early... */ - switch (nfingers_down) { - default: - log_tfd_bug(tp, event, nfingers_down); - break; // bug - case 3: -- /* perform a press since it hasn't already been done by the timer */ -+ if (clickpad_pressed) -+ break; -+ -+ /* show special consideration for overlapping hold gestures */ -+ tp_tfd_interrupt_gestures(tp, t, time); -+ - tp->tfd.state = TFD_STATE_DRAG; - tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED); - tp_tfd_clear_timer(tp); -@@ -292,8 +327,12 @@ tp_tfd_possible_drag_handle_event(struct tp_dispatch *tp, - case TFD_EVENT_RESUME_TIMEOUT: - break; - case TFD_EVENT_TIMEOUT: -- /* we've not moved our three fingers so we perform the press after the -- initial delay */ -+ if (clickpad_pressed) -+ break; -+ -+ /* show special consideration for overlapping hold gestures */ -+ tp_tfd_interrupt_gestures(tp, t, time); -+ - tp->tfd.state = TFD_STATE_DRAG; - tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED); - break; -@@ -658,6 +697,26 @@ tp_tfd_possible_resume_handle_event(struct tp_dispatch *tp, - // TODO: It's too easy to trigger 3fd while scrolling and a third finger - // touches momentarily. */ - -+/* Whether to disregard this event for the current state instead of handling it */ -+// static bool -+// tp_tfd_should_filter_event(struct tp_dispatch *tp, -+// struct tp_touch *t, -+// enum tfd_event event, -+// uint64_t time, -+// int nfingers_down) -+// { -+// switch (tp->tfd.state) { -+// case TFD_STATE_POSSIBLE_DRAG: -+// /* don't engage TFD while clickpad is pressed */ -+// return (event == TFD_EVENT_MOTION || event == TFD_EVENT_TIMEOUT) && -+// tp->buttons.is_clickpad && tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS; -+// /* TODO: not very clean since motion and timeouts aren't directly -+// related to entering the drag state. Consider a more clear solution. */ -+// default: -+// return false; -+// } -+// } -+ - static void - tp_tfd_handle_event(struct tp_dispatch *tp, - struct tp_touch *t, -@@ -684,6 +743,12 @@ tp_tfd_handle_event(struct tp_dispatch *tp, - break; - } - -+ // /* currently used to prevent TFD while clickpad button is pressed */ -+ // /* TODO: consider just inspecting the clickpad state in the POSSIBLE_DRAG -+ // handler to at least gather all state transition decisions in one place? */ -+ // if (tp_tfd_should_filter_event(tp, t, event, time, nfingers_down)) -+ // return; -+ - switch(tp->tfd.state) { - case TFD_STATE_IDLE: - tp_tfd_idle_handle_event(tp, t, event, time, nfingers_down); -@@ -833,7 +898,7 @@ tp_tfd_handle_state(struct tp_dispatch *tp, uint64_t time) - // if (!tp_tfd_enabled(tp)) - // return 0; - -- /* Handle queued button pressed events from clickpads. */ -+ /* Handle queued button pressed events. */ - if (/* tp->buttons.is_clickpad && */ tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS) - tp_tfd_handle_event(tp, NULL, TFD_EVENT_BUTTON, time, active_touches); - --- -2.47.1 - diff --git a/0005-Debounce-for-4-fingers-before-drag-starts.patch b/0005-Debounce-for-4-fingers-before-drag-starts.patch deleted file mode 100644 index bc5f2b0410e1..000000000000 --- a/0005-Debounce-for-4-fingers-before-drag-starts.patch +++ /dev/null @@ -1,174 +0,0 @@ -From ecaf93d377c945d4282cda023e5070b9f486add3 Mon Sep 17 00:00:00 2001 -From: abc def <24701-abcdef@users.noreply.gitlab.freedesktop.org> -Date: Mon, 7 Feb 2022 15:44:00 +0100 -Subject: [PATCH 5/7] Debounce for 4+ fingers before drag starts - -When the drag hasn't started there's now a 50 ms debounce time -to disambiguate from 4+ finger gestures. ---- - src/evdev-mt-touchpad-tfd.c | 89 +++++++++++++++++++++++++++++++++---- - src/evdev-mt-touchpad.h | 6 ++- - 2 files changed, 85 insertions(+), 10 deletions(-) - -diff --git a/src/evdev-mt-touchpad-tfd.c b/src/evdev-mt-touchpad-tfd.c -index c1c32862..d9a27c8a 100644 ---- a/src/evdev-mt-touchpad-tfd.c -+++ b/src/evdev-mt-touchpad-tfd.c -@@ -42,7 +42,8 @@ tfd_state_to_str(enum tp_tfd_state state) - { - switch(state) { - CASE_RETURN_STRING(TFD_STATE_IDLE); -- CASE_RETURN_STRING(TFD_STATE_POSSIBLE_DRAG); -+ CASE_RETURN_STRING(TFD_STATE_POSSIBLE_BEGIN); -+ CASE_RETURN_STRING(TFD_STATE_AWAIT_DRAG); - CASE_RETURN_STRING(TFD_STATE_DRAG); - CASE_RETURN_STRING(TFD_STATE_POSSIBLE_ZERO_FINGERS); - CASE_RETURN_STRING(TFD_STATE_AWAIT_RESUME); -@@ -239,8 +240,9 @@ tp_tfd_idle_handle_event(struct tp_dispatch *tp, - case TFD_EVENT_TOUCH_COUNT_INCREASE: - case TFD_EVENT_TOUCH_COUNT_DECREASE: - if (nfingers_down == 3) { -- tp->tfd.state = TFD_STATE_POSSIBLE_DRAG; -- tp_tfd_set_button_press_delay_timer(tp, time); -+ tp->tfd.state = TFD_STATE_POSSIBLE_BEGIN; -+ // tp_tfd_set_button_press_delay_timer(tp, time); -+ tp_tfd_set_await_more_fingers_timer(tp, time); - } - break; - case TFD_EVENT_MOTION: -@@ -255,6 +257,72 @@ tp_tfd_idle_handle_event(struct tp_dispatch *tp, - } - } - -+ -+ -+ -+ -+/* Waiting for more fingers. Three fingers have been detected, but it might be -+a transitory phase towards 4 or more fingers, which should not begin the -+drag. */ -+static void -+tp_tfd_possible_begin_handle_event(struct tp_dispatch *tp, -+ struct tp_touch *t, -+ enum tfd_event event, uint64_t time, -+ int nfingers_down) -+{ -+ switch (event) { -+ case TFD_EVENT_TOUCH_COUNT_INCREASE: -+ switch (nfingers_down) { -+ case 0: -+ case 1: -+ case 2: -+ case 3: -+ break; // bug? -+ default: -+ tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_timer(tp); -+ break; -+ } -+ break; -+ case TFD_EVENT_MOTION: -+ break; -+ case TFD_EVENT_RESUME_TIMEOUT: -+ break; // bug -+ case TFD_EVENT_TOUCH_COUNT_DECREASE: -+ /* a decrease forces immediate evaluation as if the timer had fired */ -+ tp_tfd_clear_timer(tp); -+ /* fallthrough */ -+ case TFD_EVENT_TIMEOUT: -+ /* time to check whether we have 3 fingers touching */ -+ switch (nfingers_down) { -+ case 0: -+ case 1: -+ case 2: -+ default: -+ tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ break; -+ case 3: -+ tp_tfd_unpin_fingers(tp); -+ // TODO: compensate for the duration of this state -+ tp_tfd_set_button_press_delay_timer(tp, time); -+ tp->tfd.state = TFD_STATE_AWAIT_DRAG; -+ break; -+ } -+ break; -+ case TFD_EVENT_TAP: -+ case TFD_EVENT_BUTTON: -+ tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_timer(tp); -+ break; -+ } -+} -+ -+ -+ -+ - /* finishes hold gestures and cancels other gestures */ - static void - tp_tfd_interrupt_gestures(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time) -@@ -280,7 +348,7 @@ tp_tfd_interrupt_gestures(struct tp_dispatch *tp, struct tp_touch *t, uint64_t t - /* We don't have the primary button pressed in this state; the - press is delayed if the fingers have remained stationary */ - static void --tp_tfd_possible_drag_handle_event(struct tp_dispatch *tp, -+tp_tfd_await_drag_handle_event(struct tp_dispatch *tp, - struct tp_touch *t, - enum tfd_event event, uint64_t time, int nfingers_down) - { -@@ -754,8 +822,12 @@ tp_tfd_handle_event(struct tp_dispatch *tp, - tp_tfd_idle_handle_event(tp, t, event, time, nfingers_down); - break; - -- case TFD_STATE_POSSIBLE_DRAG: -- tp_tfd_possible_drag_handle_event(tp, t, event, time, nfingers_down); -+ case TFD_STATE_POSSIBLE_BEGIN: -+ tp_tfd_possible_begin_handle_event(tp, t, event, time, nfingers_down); -+ break; -+ -+ case TFD_STATE_AWAIT_DRAG: -+ tp_tfd_await_drag_handle_event(tp, t, event, time, nfingers_down); - break; - - case TFD_STATE_DRAG: -@@ -826,7 +898,7 @@ tp_tfd_exceeds_motion_threshold(struct tp_dispatch *tp, - return false; - - double threshold = DEFAULT_TFD_MOVE_THRESHOLD; -- if (tp->tfd.state == TFD_STATE_POSSIBLE_DRAG) { -+ if (tp->tfd.state == TFD_STATE_AWAIT_DRAG) { - // TODO: have to figure out something better - // MOTION events are too decoupled from what's required to actually move - // the cursor. TODO: look it up -@@ -967,7 +1039,8 @@ tp_tfd_handle_tap(struct tp_dispatch *tp, uint64_t time) - tp_tfd_handle_event(tp, NULL, TFD_EVENT_TAP, time, tp->tfd.finger_count); - break; - case TFD_STATE_IDLE: -- case TFD_STATE_POSSIBLE_DRAG: -+ case TFD_STATE_POSSIBLE_BEGIN: -+ case TFD_STATE_AWAIT_DRAG: - case TFD_STATE_DRAG: - break; - } -diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h -index 3e464869..ec64b747 100644 ---- a/src/evdev-mt-touchpad.h -+++ b/src/evdev-mt-touchpad.h -@@ -141,8 +141,10 @@ enum tp_tfd_state { - - /* waiting for 3 fingers */ - TFD_STATE_IDLE, -- /* 3 fingers touching, possible 4+ f gesture */ -- TFD_STATE_POSSIBLE_DRAG, -+ /* [debounce] disambiguate between starting a drag and a possible 4+ gesture */ -+ TFD_STATE_POSSIBLE_BEGIN, -+ /* 3 fingers touching, waiting for motion or timeout */ -+ TFD_STATE_AWAIT_DRAG, - /* 3 fingers touching and button press has been output */ - TFD_STATE_DRAG, - /* [debounce] drag-lock; 1 finger touching, possibly going to 0 fingers */ --- -2.47.1 - diff --git a/0006-Cancel-hold-gestures-instead-of-finishing-them.patch b/0006-Cancel-hold-gestures-instead-of-finishing-them.patch deleted file mode 100644 index b54be2011233..000000000000 --- a/0006-Cancel-hold-gestures-instead-of-finishing-them.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 07847ab985708e6b280607036d886af312dcc397 Mon Sep 17 00:00:00 2001 -From: abc def <24701-abcdef@users.noreply.gitlab.freedesktop.org> -Date: Mon, 7 Feb 2022 16:19:01 +0100 -Subject: [PATCH 6/7] Cancel hold gestures instead of finishing them - -It was requested that we should be consistent here with what happens when swipe gestures interrupt hold gestures. ---- - src/evdev-mt-touchpad-tfd.c | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/src/evdev-mt-touchpad-tfd.c b/src/evdev-mt-touchpad-tfd.c -index d9a27c8a..33fb4a06 100644 ---- a/src/evdev-mt-touchpad-tfd.c -+++ b/src/evdev-mt-touchpad-tfd.c -@@ -331,12 +331,12 @@ tp_tfd_interrupt_gestures(struct tp_dispatch *tp, struct tp_touch *t, uint64_t t - case GESTURE_STATE_NONE: - case GESTURE_STATE_POINTER_MOTION: - break; /* should be harmless enough? */ -- case GESTURE_STATE_HOLD: -- case GESTURE_STATE_HOLD_AND_MOTION: -- /* starting a drag should finish a hold gesture -- not -- cancel it (if there's any difference?) */ -- tp_gesture_stop(tp, time); -- break; -+ // case GESTURE_STATE_HOLD: -+ // case GESTURE_STATE_HOLD_AND_MOTION: -+ // /* starting a drag should finish a hold gesture -- not -+ // cancel it (if there's any difference?) */ -+ // tp_gesture_stop(tp, time); -+ // break; - default: - tp_gesture_cancel(tp, time); - break; --- -2.47.1 - diff --git a/0007-Abort-TFD-within-50-ms-on-detection-of-4-fingers.patch b/0007-Abort-TFD-within-50-ms-on-detection-of-4-fingers.patch deleted file mode 100644 index f1e9eef7c613..000000000000 --- a/0007-Abort-TFD-within-50-ms-on-detection-of-4-fingers.patch +++ /dev/null @@ -1,402 +0,0 @@ -From c703c263a9aae5df6419abf2ba20e23a061da821 Mon Sep 17 00:00:00 2001 -From: abc def <24701-abcdef@users.noreply.gitlab.freedesktop.org> -Date: Mon, 14 Feb 2022 13:59:11 +0100 -Subject: [PATCH 7/7] Abort TFD within 50 ms on detection of 4+ fingers - -Improved method of disambiguating between three finger drags and four finger gestures. ---- - src/evdev-mt-touchpad-tfd.c | 239 ++++++++++++++++++++++++------------ - src/evdev-mt-touchpad.h | 12 +- - 2 files changed, 169 insertions(+), 82 deletions(-) - -diff --git a/src/evdev-mt-touchpad-tfd.c b/src/evdev-mt-touchpad-tfd.c -index 33fb4a06..681beedf 100644 ---- a/src/evdev-mt-touchpad-tfd.c -+++ b/src/evdev-mt-touchpad-tfd.c -@@ -7,7 +7,7 @@ - #include "evdev-mt-touchpad.h" - - /* when three fingers are detected, this is how long we wait to see if the user --actually intends a 3 finger gesture, or is transitioning to e.g. 4 fingers */ -+actually intends a 3 finger gesture or is transitioning to e.g. 4 fingers */ - #define DEFAULT_DRAG3_WAIT_FOR_FINGERS_DURATION ms2us(50) - /* The interval between three fingers touching and a button press being - performed, if the fingers remain stationary */ -@@ -42,8 +42,9 @@ tfd_state_to_str(enum tp_tfd_state state) - { - switch(state) { - CASE_RETURN_STRING(TFD_STATE_IDLE); -- CASE_RETURN_STRING(TFD_STATE_POSSIBLE_BEGIN); -+ // CASE_RETURN_STRING(TFD_STATE_POSSIBLE_BEGIN); - CASE_RETURN_STRING(TFD_STATE_AWAIT_DRAG); -+ CASE_RETURN_STRING(TFD_STATE_DRAG_AND_DEBOUNCE); - CASE_RETURN_STRING(TFD_STATE_DRAG); - CASE_RETURN_STRING(TFD_STATE_POSSIBLE_ZERO_FINGERS); - CASE_RETURN_STRING(TFD_STATE_AWAIT_RESUME); -@@ -237,12 +238,15 @@ tp_tfd_idle_handle_event(struct tp_dispatch *tp, - enum tfd_event event, uint64_t time, int nfingers_down) - { - switch (event) { -- case TFD_EVENT_TOUCH_COUNT_INCREASE: - case TFD_EVENT_TOUCH_COUNT_DECREASE: -+ /* turns out it's distracting to accidentally initiate dragging while -+ removing fingers after a 4+ swipe gesture. */ -+ break; -+ case TFD_EVENT_TOUCH_COUNT_INCREASE: - if (nfingers_down == 3) { -- tp->tfd.state = TFD_STATE_POSSIBLE_BEGIN; -- // tp_tfd_set_button_press_delay_timer(tp, time); -- tp_tfd_set_await_more_fingers_timer(tp, time); -+ tp->tfd.state = TFD_STATE_AWAIT_DRAG; -+ tp_tfd_set_button_press_delay_timer(tp, time); -+ // tp_tfd_set_await_more_fingers_timer(tp, time); - } - break; - case TFD_EVENT_MOTION: -@@ -260,70 +264,70 @@ tp_tfd_idle_handle_event(struct tp_dispatch *tp, - - - -- -+// unused -- TODO: remove if drag_and_debounce is successful - /* Waiting for more fingers. Three fingers have been detected, but it might be - a transitory phase towards 4 or more fingers, which should not begin the - drag. */ --static void --tp_tfd_possible_begin_handle_event(struct tp_dispatch *tp, -- struct tp_touch *t, -- enum tfd_event event, uint64_t time, -- int nfingers_down) --{ -- switch (event) { -- case TFD_EVENT_TOUCH_COUNT_INCREASE: -- switch (nfingers_down) { -- case 0: -- case 1: -- case 2: -- case 3: -- break; // bug? -- default: -- tp_tfd_unpin_fingers(tp); -- tp->tfd.state = TFD_STATE_IDLE; -- tp_tfd_clear_timer(tp); -- break; -- } -- break; -- case TFD_EVENT_MOTION: -- break; -- case TFD_EVENT_RESUME_TIMEOUT: -- break; // bug -- case TFD_EVENT_TOUCH_COUNT_DECREASE: -- /* a decrease forces immediate evaluation as if the timer had fired */ -- tp_tfd_clear_timer(tp); -- /* fallthrough */ -- case TFD_EVENT_TIMEOUT: -- /* time to check whether we have 3 fingers touching */ -- switch (nfingers_down) { -- case 0: -- case 1: -- case 2: -- default: -- tp_tfd_unpin_fingers(tp); -- tp->tfd.state = TFD_STATE_IDLE; -- break; -- case 3: -- tp_tfd_unpin_fingers(tp); -- // TODO: compensate for the duration of this state -- tp_tfd_set_button_press_delay_timer(tp, time); -- tp->tfd.state = TFD_STATE_AWAIT_DRAG; -- break; -- } -- break; -- case TFD_EVENT_TAP: -- case TFD_EVENT_BUTTON: -- tp_tfd_unpin_fingers(tp); -- tp->tfd.state = TFD_STATE_IDLE; -- tp_tfd_clear_timer(tp); -- break; -- } --} -+// static void -+// tp_tfd_possible_begin_handle_event(struct tp_dispatch *tp, -+// struct tp_touch *t, -+// enum tfd_event event, uint64_t time, -+// int nfingers_down) -+// { -+// switch (event) { -+// case TFD_EVENT_TOUCH_COUNT_INCREASE: -+// switch (nfingers_down) { -+// case 0: -+// case 1: -+// case 2: -+// case 3: -+// break; // bug? -+// default: -+// tp_tfd_unpin_fingers(tp); -+// tp->tfd.state = TFD_STATE_IDLE; -+// tp_tfd_clear_timer(tp); -+// break; -+// } -+// break; -+// case TFD_EVENT_MOTION: -+// break; -+// case TFD_EVENT_RESUME_TIMEOUT: -+// break; // bug -+// case TFD_EVENT_TOUCH_COUNT_DECREASE: -+// /* a decrease forces immediate evaluation as if the timer had fired */ -+// tp_tfd_clear_timer(tp); -+// /* fallthrough */ -+// case TFD_EVENT_TIMEOUT: -+// /* time to check whether we have 3 fingers touching */ -+// switch (nfingers_down) { -+// case 0: -+// case 1: -+// case 2: -+// default: -+// tp_tfd_unpin_fingers(tp); -+// tp->tfd.state = TFD_STATE_IDLE; -+// break; -+// case 3: -+// tp_tfd_unpin_fingers(tp); -+// // TODO: compensate for the duration of this state -+// tp_tfd_set_button_press_delay_timer(tp, time); -+// tp->tfd.state = TFD_STATE_AWAIT_DRAG; -+// break; -+// } -+// break; -+// case TFD_EVENT_TAP: -+// case TFD_EVENT_BUTTON: -+// tp_tfd_unpin_fingers(tp); -+// tp->tfd.state = TFD_STATE_IDLE; -+// tp_tfd_clear_timer(tp); -+// break; -+// } -+// } - - - - --/* finishes hold gestures and cancels other gestures */ -+/* takes appropriate action to cancel or finish a gesture in progress */ - static void - tp_tfd_interrupt_gestures(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time) - { -@@ -387,9 +391,10 @@ tp_tfd_await_drag_handle_event(struct tp_dispatch *tp, - /* show special consideration for overlapping hold gestures */ - tp_tfd_interrupt_gestures(tp, t, time); - -- tp->tfd.state = TFD_STATE_DRAG; -+ // tp_tfd_clear_timer(tp); -+ tp_tfd_set_await_more_fingers_timer(tp, time); -+ tp->tfd.state = TFD_STATE_DRAG_AND_DEBOUNCE; - tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED); -- tp_tfd_clear_timer(tp); - } - break; - case TFD_EVENT_RESUME_TIMEOUT: -@@ -401,14 +406,18 @@ tp_tfd_await_drag_handle_event(struct tp_dispatch *tp, - /* show special consideration for overlapping hold gestures */ - tp_tfd_interrupt_gestures(tp, t, time); - -- tp->tfd.state = TFD_STATE_DRAG; -+ tp_tfd_set_await_more_fingers_timer(tp, time); -+ tp->tfd.state = TFD_STATE_DRAG_AND_DEBOUNCE; - tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED); - break; - case TFD_EVENT_TAP: - case TFD_EVENT_BUTTON: - // TODO: undecided - //tp->tfd.state = TFD_STATE_IDLE; -- //tp_tfd_clear_timer(tp); -+ /* if a button is pressed while waiting for timeout, cancel the timeout -+ since it will most likely just result in a somewhat unanticipated second -+ button press */ -+ tp_tfd_clear_timer(tp); - break; - } - } -@@ -419,6 +428,71 @@ tp_tfd_await_drag_handle_event(struct tp_dispatch *tp, - position updates -- use the fastest finger only */ - - -+/* Brief cancellable drag state to disambiguate between drag and a 4+ finger swipe. -+Otherwise same as the drag state. Replaces POSSIBLE_BEGIN state. */ -+static void -+tp_tfd_drag_and_debounce_handle_event(struct tp_dispatch *tp, -+ struct tp_touch *t, -+ enum tfd_event event, uint64_t time, -+ int nfingers_down) -+{ -+ switch (event) { -+ // case TFD_EVENT_TOUCH_COUNT: -+ case TFD_EVENT_TOUCH_COUNT_INCREASE: -+ case TFD_EVENT_TOUCH_COUNT_DECREASE: -+ switch (nfingers_down) { -+ case 0: -+ tp_tfd_pin_fingers(tp); -+ tp_tfd_set_await_resume_timer(tp, time); -+ tp->tfd.state = TFD_STATE_AWAIT_RESUME; -+ -+ // tp_tfd_pin_fingers(tp); -+ // tp_tfd_set_await_resume_timer(tp, time); -+ // tp_tfd_set_await_more_fingers_timer(tp, time); -+ // tp->tfd.state = TFD_STATE_POSSIBLE_RESUME; -+ -+ break; -+ case 1: -+ tp_tfd_pin_fingers(tp); -+ tp_tfd_set_await_resume_timer(tp, time); -+ tp_tfd_set_await_more_fingers_timer(tp, time); -+ tp->tfd.state = TFD_STATE_POSSIBLE_ZERO_FINGERS; -+ break; -+ case 2: -+ /* Seems far-fetched to interpret 0 -> 3 -> 2 fingers as an intent -+ to scroll. Fallthrough. */ -+ case 3: -+ break; -+ default: -+ /* 4+ fingers; the drag should abort to give way to 4+ finger -+ gestures */ -+ // tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_timer(tp); -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ break; -+ } -+ break; -+ case TFD_EVENT_MOTION: -+ break; -+ case TFD_EVENT_RESUME_TIMEOUT: -+ log_tfd_bug(tp, event, nfingers_down); -+ break; // bug -+ case TFD_EVENT_TIMEOUT: -+ // 4+ finger gesture didn't happen -- time to exit the debounce state -+ tp->tfd.state = TFD_STATE_DRAG; -+ break; -+ case TFD_EVENT_TAP: -+ break; -+ case TFD_EVENT_BUTTON: -+ // tp_tfd_unpin_fingers(tp); -+ tp->tfd.state = TFD_STATE_IDLE; -+ tp_tfd_clear_timer(tp); -+ tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); -+ break; -+ } -+} -+ - static void - tp_tfd_drag_handle_event(struct tp_dispatch *tp, - struct tp_touch *t, -@@ -462,7 +536,6 @@ tp_tfd_drag_handle_event(struct tp_dispatch *tp, - case TFD_EVENT_BUTTON: - tp_tfd_unpin_fingers(tp); - tp->tfd.state = TFD_STATE_IDLE; -- tp_tfd_clear_resume_timer(tp); - tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); - break; - } -@@ -797,7 +870,6 @@ tp_tfd_handle_event(struct tp_dispatch *tp, - previous_state = tp->tfd.state; - - assert(nfingers_down >= 0); -- // assert(nfingers_down < 6); // TODO: temp, remove - - switch (event) { - case TFD_EVENT_MOTION: -@@ -822,14 +894,18 @@ tp_tfd_handle_event(struct tp_dispatch *tp, - tp_tfd_idle_handle_event(tp, t, event, time, nfingers_down); - break; - -- case TFD_STATE_POSSIBLE_BEGIN: -- tp_tfd_possible_begin_handle_event(tp, t, event, time, nfingers_down); -- break; -+ // case TFD_STATE_POSSIBLE_BEGIN: -+ // tp_tfd_possible_begin_handle_event(tp, t, event, time, nfingers_down); -+ // break; - - case TFD_STATE_AWAIT_DRAG: - tp_tfd_await_drag_handle_event(tp, t, event, time, nfingers_down); - break; - -+ case TFD_STATE_DRAG_AND_DEBOUNCE: -+ tp_tfd_drag_and_debounce_handle_event(tp, t, event, time, nfingers_down); -+ break; -+ - case TFD_STATE_DRAG: - tp_tfd_drag_handle_event(tp, t, event, time, nfingers_down); - break; -@@ -1033,16 +1109,17 @@ void - tp_tfd_handle_tap(struct tp_dispatch *tp, uint64_t time) - { - switch (tp->tfd.state) { -+ case TFD_STATE_IDLE: -+ // case TFD_STATE_POSSIBLE_BEGIN: -+ case TFD_STATE_AWAIT_DRAG: -+ case TFD_STATE_DRAG_AND_DEBOUNCE: -+ case TFD_STATE_DRAG: -+ break; - case TFD_STATE_POSSIBLE_ZERO_FINGERS: - case TFD_STATE_AWAIT_RESUME: - case TFD_STATE_POSSIBLE_RESUME: - tp_tfd_handle_event(tp, NULL, TFD_EVENT_TAP, time, tp->tfd.finger_count); - break; -- case TFD_STATE_IDLE: -- case TFD_STATE_POSSIBLE_BEGIN: -- case TFD_STATE_AWAIT_DRAG: -- case TFD_STATE_DRAG: -- break; - } - } - -@@ -1101,12 +1178,16 @@ bool - tp_tfd_dragging(const struct tp_dispatch *tp) - { - switch (tp->tfd.state) { -+ case TFD_STATE_IDLE: -+ case TFD_STATE_AWAIT_DRAG: -+ return false; -+ case TFD_STATE_DRAG_AND_DEBOUNCE: - case TFD_STATE_DRAG: -+ case TFD_STATE_POSSIBLE_ZERO_FINGERS: - case TFD_STATE_AWAIT_RESUME: - case TFD_STATE_POSSIBLE_RESUME: - return true; -- default: -- return false; - } -+ return false; - } - -diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h -index ec64b747..5553726d 100644 ---- a/src/evdev-mt-touchpad.h -+++ b/src/evdev-mt-touchpad.h -@@ -141,16 +141,22 @@ enum tp_tfd_state { - - /* waiting for 3 fingers */ - TFD_STATE_IDLE, -- /* [debounce] disambiguate between starting a drag and a possible 4+ gesture */ -- TFD_STATE_POSSIBLE_BEGIN, -+ // not used -- TODO: remove after testing drag_and_debounce -+ // /* [debounce] disambiguate between starting a drag and a possible 4+ gesture */ -+ // TFD_STATE_POSSIBLE_BEGIN, - /* 3 fingers touching, waiting for motion or timeout */ - TFD_STATE_AWAIT_DRAG, -+ /* [debounce] same as drag state, but cancellable in case of possible 4+ -+ gesture. Replacement state for POSSIBLE_BEGIN */ -+ TFD_STATE_DRAG_AND_DEBOUNCE, - /* 3 fingers touching and button press has been output */ - TFD_STATE_DRAG, -- /* [debounce] drag-lock; 1 finger touching, possibly going to 0 fingers */ -+ /* [debounce] drag-lock; 1 finger touching, possibly going to 0 fingers. -+ Prevents premature cancellation of AWAIT_RESUME by 1 finger motion events. */ - TFD_STATE_POSSIBLE_ZERO_FINGERS, - /* drag-lock; waiting for 3 finger drag continuation */ - TFD_STATE_AWAIT_RESUME, -+ /* TODO: possible to replace this state with DRAG_AND_DEBOUNCE as well? */ - /* [debounce] disambiguate between drag continuation and a possible 4+ gesture */ - TFD_STATE_POSSIBLE_RESUME, - }; --- -2.47.1 - @@ -1,67 +1,53 @@ -# Maintainer: éclairevoyant -# Contributor: Jasper van Bourgognie <louiecaulfield at gmail dot com> -# Contributor: Andreas Radke <andyrtr at archlinux dot org> +# Maintainer: Jasper van Bourgognie <louiecaulfield at gmail dot com> +# Contributor: Andreas Radke <andyrtr@archlinux.org> _pkgname=libinput pkgname="$_pkgname-three-finger-drag" -pkgver=1.27.1 +pkgver=1.28.1 pkgrel=1 pkgdesc="Input device management and event handling library" -url="https://www.freedesktop.org/wiki/Software/$_pkgname/" +url="https://gitlab.freedesktop.org/libinput/libinput" arch=(x86_64) -license=(custom:X11) +license=(MIT) provides=("$_pkgname=$pkgver") conflicts=("$_pkgname") -depends=(libevdev libwacom mtdev systemd) +depends=('mtdev' 'libevdev' 'libwacom' 'systemd-libs' 'glibc') # upstream doesn't recommend building docs -makedepends=(check git gtk4 meson wayland-protocols) -checkdepends=(python-pytest) +makedepends=('gtk4' 'meson' 'wayland-protocols' 'check') # 'doxygen' 'graphviz' 'python-sphinx' 'python-recommonmark' +checkdepends=('python-pytest') optdepends=('gtk4: libinput debug-gui' 'python-pyudev: libinput measure' - 'python-libevdev: libinput measure') + 'python-libevdev: libinput measure' + 'python-yaml: used by various tools') source=("git+https://gitlab.freedesktop.org/$_pkgname/$_pkgname.git?signed#tag=$pkgver" - 0001-Three-finger-dragging-TFD-state-machine.patch - 0002-Cleanup.patch - 0003-TFD-add-debounce-state-for-touch-count-decrease.patch - 0004-Take-hold-gestures-and-clickpad-state-into-account.patch - 0005-Debounce-for-4-fingers-before-drag-starts.patch - 0006-Cancel-hold-gestures-instead-of-finishing-them.patch - 0007-Abort-TFD-within-50-ms-on-detection-of-4-fingers.patch + 0001-gestures-fix-acceleration-in-3fg-drag.patch + 0002-enable-3fg-drag-by-default.patch ) b2sums=('SKIP' - '94fb25e198d9a7d8fa05beb398edc0a384d2062c81ca9dc5131c566b97456461eeb5c277873ccf679456ac62bb5432c85ba21e8c5f24ef12d5aa5f05a8ba32f8' - '1e409a1062464942661002aa4fd1f7603e9e03c70dab182e59e9ea66caf63ee09051fbfadcb71e76068f3b0286ed08abcff8d3678c846ad971705db710e4d071' - 'ca5f43ee91c732807c4a155b3f7f1e128afa875122302264eef8d63f784f0723fe64754f2ece7dd46a35774798698184e7fdb3ab04ef33da7d1ec39b7c4a69d8' - '89e187b97eb7eb824ef1f65efe0a631663b641a18eadb62ee147dfabea40269311cd2c9e2591648411254a4d665ee41d00357c209d90d10acc7e63e54d6e0c97' - 'd909898f54d516a22c479f8b7ce7a419071172a092311d1d39aade3d430ec95924f30ecead23f94affddbeaf904f12098631b985f98929cd2e44f1c5e9e075b0' - 'fce7d335eed9dce132508d35f04835faedf1a73c3910d6542e7e0e537b3ce5acacdf7fc50ef9975f4815bf224879f9284f884d228abef4297c2b8579d7fa74de' - 'f58be0c19ec9afb087078037f12935526c2a275ce8ce37fdc6c1165a64d3fb4fa78c6458c18f0b51b3cfa21f6260ae21603e13c2d854979a2df58176e2965b1b' + 'ce6e69d41343dbbcee4757b174cf0fb9db6b2dd665a5b0ec248dbb5e76ac9afa38c599d65dc8e86f78475ec518c366a6358c2181a44e7fa629d28a62cf5db9b3' + '3332b93d09da6d1c0150c365257aee1f6be7d4ce961849a312e62113ade3eda3c1b01e916e6482f1023641055af3899cab70dee431ca4b2c61ae5d35d4329918' ) validpgpkeys=('3C2C43D9447D5938EF4551EBE23B7E70B467F0BF') # Peter Hutterer (Who-T) <office@who-t.net> prepare() { cd $_pkgname - patch -Np1 -i "$srcdir/0001-Three-finger-dragging-TFD-state-machine.patch" - patch -Np1 -i "$srcdir/0002-Cleanup.patch" - patch -Np1 -i "$srcdir/0003-TFD-add-debounce-state-for-touch-count-decrease.patch" - patch -Np1 -i "$srcdir/0004-Take-hold-gestures-and-clickpad-state-into-account.patch" - patch -Np1 -i "$srcdir/0005-Debounce-for-4-fingers-before-drag-starts.patch" - patch -Np1 -i "$srcdir/0006-Cancel-hold-gestures-instead-of-finishing-them.patch" - patch -Np1 -i "$srcdir/0007-Abort-TFD-within-50-ms-on-detection-of-4-fingers.patch" + patch -Np1 -i "$srcdir/0001-gestures-fix-acceleration-in-3fg-drag.patch" + patch -Np1 -i "$srcdir/0002-enable-3fg-drag-by-default.patch" } build() { - arch-meson $_pkgname build \ - -D udev-dir=/usr/lib/udev \ - -D documentation=false - meson compile -C build + arch-meson $_pkgname build \ + -D udev-dir=/usr/lib/udev \ + -D documentation=false + meson compile -C build } check() { - meson test -C build --print-errorlogs + meson test -C build --print-errorlogs } package() { - DESTDIR="$pkgdir" meson install -C build - install -vDm644 $_pkgname/COPYING "$pkgdir/usr/share/licenses/$pkgname/LICENSE" + meson install -C build --destdir "$pkgdir" + + install -Dvm644 $_pkgname/COPYING "$pkgdir/usr/share/licenses/$_pkgname/LICENSE" } |