summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorJasper van Bourgognie2025-04-08 21:13:32 +0200
committerJasper van Bourgognie2025-04-08 21:17:51 +0200
commit68e0cf3ad1c9440d85a51bb11c5258591012ac7f (patch)
tree57e6750a2623137a5cea03556cb7457d9b037751
parent3cb50413aca02077765c1e23373bce29415caadc (diff)
downloadaur-libinput-three-finger-drag.tar.gz
Update to 1.28.1
-rw-r--r--.SRCINFO37
-rw-r--r--0001-Three-finger-dragging-TFD-state-machine.patch1505
-rw-r--r--0001-gestures-fix-acceleration-in-3fg-drag.patch40
-rw-r--r--0002-Cleanup.patch987
-rw-r--r--0002-enable-3fg-drag-by-default.patch25
-rw-r--r--0003-TFD-add-debounce-state-for-touch-count-decrease.patch205
-rw-r--r--0004-Take-hold-gestures-and-clickpad-state-into-account.patch149
-rw-r--r--0005-Debounce-for-4-fingers-before-drag-starts.patch174
-rw-r--r--0006-Cancel-hold-gestures-instead-of-finishing-them.patch36
-rw-r--r--0007-Abort-TFD-within-50-ms-on-detection-of-4-fingers.patch402
-rw-r--r--PKGBUILD62
11 files changed, 103 insertions, 3519 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 2e7bafd68194..e329ea72fd79 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -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
-
diff --git a/PKGBUILD b/PKGBUILD
index 13cf2ee398b6..6d4e759c0333 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -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"
}