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>
This commit is contained in:
abc def 2021-12-17 00:42:50 +01:00
parent e8495b8d36
commit 89ee46cd29
6 changed files with 1374 additions and 2 deletions

View file

@ -350,6 +350,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',

View file

@ -1303,7 +1303,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) {
@ -1430,7 +1430,8 @@ tp_gesture_handle_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);

View file

@ -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

1306
src/evdev-mt-touchpad-tfd.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -846,6 +846,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);
@ -1863,6 +1867,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);
@ -3777,6 +3783,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);

View file

@ -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 */
@ -250,6 +264,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;
@ -440,6 +461,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;
@ -625,6 +671,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);