mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-05-08 14:48:09 +02:00
Abort TFD within 50 ms on detection of 4+ fingers
Improved method of disambiguating between three finger drags and four finger gestures.
This commit is contained in:
parent
a2f3b497b1
commit
13c7fa6136
2 changed files with 169 additions and 82 deletions
|
|
@ -7,7 +7,7 @@
|
||||||
#include "evdev-mt-touchpad.h"
|
#include "evdev-mt-touchpad.h"
|
||||||
|
|
||||||
/* when three fingers are detected, this is how long we wait to see if the user
|
/* 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)
|
#define DEFAULT_DRAG3_WAIT_FOR_FINGERS_DURATION ms2us(50)
|
||||||
/* The interval between three fingers touching and a button press being
|
/* The interval between three fingers touching and a button press being
|
||||||
performed, if the fingers remain stationary */
|
performed, if the fingers remain stationary */
|
||||||
|
|
@ -42,8 +42,9 @@ tfd_state_to_str(enum tp_tfd_state state)
|
||||||
{
|
{
|
||||||
switch(state) {
|
switch(state) {
|
||||||
CASE_RETURN_STRING(TFD_STATE_IDLE);
|
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_AWAIT_DRAG);
|
||||||
|
CASE_RETURN_STRING(TFD_STATE_DRAG_AND_DEBOUNCE);
|
||||||
CASE_RETURN_STRING(TFD_STATE_DRAG);
|
CASE_RETURN_STRING(TFD_STATE_DRAG);
|
||||||
CASE_RETURN_STRING(TFD_STATE_POSSIBLE_ZERO_FINGERS);
|
CASE_RETURN_STRING(TFD_STATE_POSSIBLE_ZERO_FINGERS);
|
||||||
CASE_RETURN_STRING(TFD_STATE_AWAIT_RESUME);
|
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)
|
enum tfd_event event, uint64_t time, int nfingers_down)
|
||||||
{
|
{
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case TFD_EVENT_TOUCH_COUNT_INCREASE:
|
|
||||||
case TFD_EVENT_TOUCH_COUNT_DECREASE:
|
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) {
|
if (nfingers_down == 3) {
|
||||||
tp->tfd.state = TFD_STATE_POSSIBLE_BEGIN;
|
tp->tfd.state = TFD_STATE_AWAIT_DRAG;
|
||||||
// tp_tfd_set_button_press_delay_timer(tp, time);
|
tp_tfd_set_button_press_delay_timer(tp, time);
|
||||||
tp_tfd_set_await_more_fingers_timer(tp, time);
|
// tp_tfd_set_await_more_fingers_timer(tp, time);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TFD_EVENT_MOTION:
|
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
|
/* 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
|
a transitory phase towards 4 or more fingers, which should not begin the
|
||||||
drag. */
|
drag. */
|
||||||
static void
|
// static void
|
||||||
tp_tfd_possible_begin_handle_event(struct tp_dispatch *tp,
|
// tp_tfd_possible_begin_handle_event(struct tp_dispatch *tp,
|
||||||
struct tp_touch *t,
|
// struct tp_touch *t,
|
||||||
enum tfd_event event, uint64_t time,
|
// enum tfd_event event, uint64_t time,
|
||||||
int nfingers_down)
|
// int nfingers_down)
|
||||||
{
|
// {
|
||||||
switch (event) {
|
// switch (event) {
|
||||||
case TFD_EVENT_TOUCH_COUNT_INCREASE:
|
// case TFD_EVENT_TOUCH_COUNT_INCREASE:
|
||||||
switch (nfingers_down) {
|
// switch (nfingers_down) {
|
||||||
case 0:
|
// case 0:
|
||||||
case 1:
|
// case 1:
|
||||||
case 2:
|
// case 2:
|
||||||
case 3:
|
// case 3:
|
||||||
break; // bug?
|
// break; // bug?
|
||||||
default:
|
// default:
|
||||||
tp_tfd_unpin_fingers(tp);
|
// tp_tfd_unpin_fingers(tp);
|
||||||
tp->tfd.state = TFD_STATE_IDLE;
|
// tp->tfd.state = TFD_STATE_IDLE;
|
||||||
tp_tfd_clear_timer(tp);
|
// tp_tfd_clear_timer(tp);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case TFD_EVENT_MOTION:
|
// case TFD_EVENT_MOTION:
|
||||||
break;
|
// break;
|
||||||
case TFD_EVENT_RESUME_TIMEOUT:
|
// case TFD_EVENT_RESUME_TIMEOUT:
|
||||||
break; // bug
|
// break; // bug
|
||||||
case TFD_EVENT_TOUCH_COUNT_DECREASE:
|
// case TFD_EVENT_TOUCH_COUNT_DECREASE:
|
||||||
/* a decrease forces immediate evaluation as if the timer had fired */
|
// /* a decrease forces immediate evaluation as if the timer had fired */
|
||||||
tp_tfd_clear_timer(tp);
|
// tp_tfd_clear_timer(tp);
|
||||||
/* fallthrough */
|
// /* fallthrough */
|
||||||
case TFD_EVENT_TIMEOUT:
|
// case TFD_EVENT_TIMEOUT:
|
||||||
/* time to check whether we have 3 fingers touching */
|
// /* time to check whether we have 3 fingers touching */
|
||||||
switch (nfingers_down) {
|
// switch (nfingers_down) {
|
||||||
case 0:
|
// case 0:
|
||||||
case 1:
|
// case 1:
|
||||||
case 2:
|
// case 2:
|
||||||
default:
|
// default:
|
||||||
tp_tfd_unpin_fingers(tp);
|
// tp_tfd_unpin_fingers(tp);
|
||||||
tp->tfd.state = TFD_STATE_IDLE;
|
// tp->tfd.state = TFD_STATE_IDLE;
|
||||||
break;
|
// break;
|
||||||
case 3:
|
// case 3:
|
||||||
tp_tfd_unpin_fingers(tp);
|
// tp_tfd_unpin_fingers(tp);
|
||||||
// TODO: compensate for the duration of this state
|
// // TODO: compensate for the duration of this state
|
||||||
tp_tfd_set_button_press_delay_timer(tp, time);
|
// tp_tfd_set_button_press_delay_timer(tp, time);
|
||||||
tp->tfd.state = TFD_STATE_AWAIT_DRAG;
|
// tp->tfd.state = TFD_STATE_AWAIT_DRAG;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
case TFD_EVENT_TAP:
|
// case TFD_EVENT_TAP:
|
||||||
case TFD_EVENT_BUTTON:
|
// case TFD_EVENT_BUTTON:
|
||||||
tp_tfd_unpin_fingers(tp);
|
// tp_tfd_unpin_fingers(tp);
|
||||||
tp->tfd.state = TFD_STATE_IDLE;
|
// tp->tfd.state = TFD_STATE_IDLE;
|
||||||
tp_tfd_clear_timer(tp);
|
// tp_tfd_clear_timer(tp);
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* finishes hold gestures and cancels other gestures */
|
/* takes appropriate action to cancel or finish a gesture in progress */
|
||||||
static void
|
static void
|
||||||
tp_tfd_interrupt_gestures(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
|
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 */
|
/* show special consideration for overlapping hold gestures */
|
||||||
tp_tfd_interrupt_gestures(tp, t, time);
|
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_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED);
|
||||||
tp_tfd_clear_timer(tp);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TFD_EVENT_RESUME_TIMEOUT:
|
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 */
|
/* show special consideration for overlapping hold gestures */
|
||||||
tp_tfd_interrupt_gestures(tp, t, time);
|
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);
|
tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED);
|
||||||
break;
|
break;
|
||||||
case TFD_EVENT_TAP:
|
case TFD_EVENT_TAP:
|
||||||
case TFD_EVENT_BUTTON:
|
case TFD_EVENT_BUTTON:
|
||||||
// TODO: undecided
|
// TODO: undecided
|
||||||
//tp->tfd.state = TFD_STATE_IDLE;
|
//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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -419,6 +428,71 @@ tp_tfd_await_drag_handle_event(struct tp_dispatch *tp,
|
||||||
position updates -- use the fastest finger only */
|
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
|
static void
|
||||||
tp_tfd_drag_handle_event(struct tp_dispatch *tp,
|
tp_tfd_drag_handle_event(struct tp_dispatch *tp,
|
||||||
struct tp_touch *t,
|
struct tp_touch *t,
|
||||||
|
|
@ -462,7 +536,6 @@ tp_tfd_drag_handle_event(struct tp_dispatch *tp,
|
||||||
case TFD_EVENT_BUTTON:
|
case TFD_EVENT_BUTTON:
|
||||||
tp_tfd_unpin_fingers(tp);
|
tp_tfd_unpin_fingers(tp);
|
||||||
tp->tfd.state = TFD_STATE_IDLE;
|
tp->tfd.state = TFD_STATE_IDLE;
|
||||||
tp_tfd_clear_resume_timer(tp);
|
|
||||||
tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
|
tp_tfd_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -797,7 +870,6 @@ tp_tfd_handle_event(struct tp_dispatch *tp,
|
||||||
previous_state = tp->tfd.state;
|
previous_state = tp->tfd.state;
|
||||||
|
|
||||||
assert(nfingers_down >= 0);
|
assert(nfingers_down >= 0);
|
||||||
// assert(nfingers_down < 6); // TODO: temp, remove
|
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case TFD_EVENT_MOTION:
|
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);
|
tp_tfd_idle_handle_event(tp, t, event, time, nfingers_down);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TFD_STATE_POSSIBLE_BEGIN:
|
// case TFD_STATE_POSSIBLE_BEGIN:
|
||||||
tp_tfd_possible_begin_handle_event(tp, t, event, time, nfingers_down);
|
// tp_tfd_possible_begin_handle_event(tp, t, event, time, nfingers_down);
|
||||||
break;
|
// break;
|
||||||
|
|
||||||
case TFD_STATE_AWAIT_DRAG:
|
case TFD_STATE_AWAIT_DRAG:
|
||||||
tp_tfd_await_drag_handle_event(tp, t, event, time, nfingers_down);
|
tp_tfd_await_drag_handle_event(tp, t, event, time, nfingers_down);
|
||||||
break;
|
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:
|
case TFD_STATE_DRAG:
|
||||||
tp_tfd_drag_handle_event(tp, t, event, time, nfingers_down);
|
tp_tfd_drag_handle_event(tp, t, event, time, nfingers_down);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1033,16 +1109,17 @@ void
|
||||||
tp_tfd_handle_tap(struct tp_dispatch *tp, uint64_t time)
|
tp_tfd_handle_tap(struct tp_dispatch *tp, uint64_t time)
|
||||||
{
|
{
|
||||||
switch (tp->tfd.state) {
|
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_POSSIBLE_ZERO_FINGERS:
|
||||||
case TFD_STATE_AWAIT_RESUME:
|
case TFD_STATE_AWAIT_RESUME:
|
||||||
case TFD_STATE_POSSIBLE_RESUME:
|
case TFD_STATE_POSSIBLE_RESUME:
|
||||||
tp_tfd_handle_event(tp, NULL, TFD_EVENT_TAP, time, tp->tfd.finger_count);
|
tp_tfd_handle_event(tp, NULL, TFD_EVENT_TAP, time, tp->tfd.finger_count);
|
||||||
break;
|
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)
|
tp_tfd_dragging(const struct tp_dispatch *tp)
|
||||||
{
|
{
|
||||||
switch (tp->tfd.state) {
|
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_DRAG:
|
||||||
|
case TFD_STATE_POSSIBLE_ZERO_FINGERS:
|
||||||
case TFD_STATE_AWAIT_RESUME:
|
case TFD_STATE_AWAIT_RESUME:
|
||||||
case TFD_STATE_POSSIBLE_RESUME:
|
case TFD_STATE_POSSIBLE_RESUME:
|
||||||
return true;
|
return true;
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -141,16 +141,22 @@ enum tp_tfd_state {
|
||||||
|
|
||||||
/* waiting for 3 fingers */
|
/* waiting for 3 fingers */
|
||||||
TFD_STATE_IDLE,
|
TFD_STATE_IDLE,
|
||||||
/* [debounce] disambiguate between starting a drag and a possible 4+ gesture */
|
// not used -- TODO: remove after testing drag_and_debounce
|
||||||
TFD_STATE_POSSIBLE_BEGIN,
|
// /* [debounce] disambiguate between starting a drag and a possible 4+ gesture */
|
||||||
|
// TFD_STATE_POSSIBLE_BEGIN,
|
||||||
/* 3 fingers touching, waiting for motion or timeout */
|
/* 3 fingers touching, waiting for motion or timeout */
|
||||||
TFD_STATE_AWAIT_DRAG,
|
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 */
|
/* 3 fingers touching and button press has been output */
|
||||||
TFD_STATE_DRAG,
|
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,
|
TFD_STATE_POSSIBLE_ZERO_FINGERS,
|
||||||
/* drag-lock; waiting for 3 finger drag continuation */
|
/* drag-lock; waiting for 3 finger drag continuation */
|
||||||
TFD_STATE_AWAIT_RESUME,
|
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 */
|
/* [debounce] disambiguate between drag continuation and a possible 4+ gesture */
|
||||||
TFD_STATE_POSSIBLE_RESUME,
|
TFD_STATE_POSSIBLE_RESUME,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue