touchpad: allow tap-and-drag for two-finger and three-finger taps

This commit duplicates the tap states responsible for tap-and drag (TAPPED
and all DRAGGING* states) to cover two-finger and three-finger taps;
the code for the new states is shared with the existing machinery for
one-finger tap-and-drag.

Signed-off-by: satrmb <10471-satrmb@users.noreply.gitlab.freedesktop.org>
This commit is contained in:
satrmb 2020-06-24 00:20:57 +02:00 committed by Peter Hutterer
parent 5e6d03ff19
commit 0e569077fe
4 changed files with 313 additions and 98 deletions

View file

@ -60,7 +60,9 @@ tap_state_to_str(enum tp_tap_state state)
CASE_RETURN_STRING(TAP_STATE_IDLE);
CASE_RETURN_STRING(TAP_STATE_HOLD);
CASE_RETURN_STRING(TAP_STATE_TOUCH);
CASE_RETURN_STRING(TAP_STATE_TAPPED);
CASE_RETURN_STRING(TAP_STATE_1FGTAP_TAPPED);
CASE_RETURN_STRING(TAP_STATE_2FGTAP_TAPPED);
CASE_RETURN_STRING(TAP_STATE_3FGTAP_TAPPED);
CASE_RETURN_STRING(TAP_STATE_TOUCH_2);
CASE_RETURN_STRING(TAP_STATE_TOUCH_2_HOLD);
CASE_RETURN_STRING(TAP_STATE_TOUCH_2_RELEASE);
@ -68,11 +70,21 @@ tap_state_to_str(enum tp_tap_state state)
CASE_RETURN_STRING(TAP_STATE_TOUCH_3_HOLD);
CASE_RETURN_STRING(TAP_STATE_TOUCH_3_RELEASE);
CASE_RETURN_STRING(TAP_STATE_TOUCH_3_RELEASE_2);
CASE_RETURN_STRING(TAP_STATE_DRAGGING);
CASE_RETURN_STRING(TAP_STATE_DRAGGING_WAIT);
CASE_RETURN_STRING(TAP_STATE_DRAGGING_OR_DOUBLETAP);
CASE_RETURN_STRING(TAP_STATE_DRAGGING_OR_TAP);
CASE_RETURN_STRING(TAP_STATE_DRAGGING_2);
CASE_RETURN_STRING(TAP_STATE_1FGTAP_DRAGGING);
CASE_RETURN_STRING(TAP_STATE_2FGTAP_DRAGGING);
CASE_RETURN_STRING(TAP_STATE_3FGTAP_DRAGGING);
CASE_RETURN_STRING(TAP_STATE_1FGTAP_DRAGGING_WAIT);
CASE_RETURN_STRING(TAP_STATE_2FGTAP_DRAGGING_WAIT);
CASE_RETURN_STRING(TAP_STATE_3FGTAP_DRAGGING_WAIT);
CASE_RETURN_STRING(TAP_STATE_1FGTAP_DRAGGING_OR_DOUBLETAP);
CASE_RETURN_STRING(TAP_STATE_2FGTAP_DRAGGING_OR_DOUBLETAP);
CASE_RETURN_STRING(TAP_STATE_3FGTAP_DRAGGING_OR_DOUBLETAP);
CASE_RETURN_STRING(TAP_STATE_1FGTAP_DRAGGING_OR_TAP);
CASE_RETURN_STRING(TAP_STATE_2FGTAP_DRAGGING_OR_TAP);
CASE_RETURN_STRING(TAP_STATE_3FGTAP_DRAGGING_OR_TAP);
CASE_RETURN_STRING(TAP_STATE_1FGTAP_DRAGGING_2);
CASE_RETURN_STRING(TAP_STATE_2FGTAP_DRAGGING_2);
CASE_RETURN_STRING(TAP_STATE_3FGTAP_DRAGGING_2);
CASE_RETURN_STRING(TAP_STATE_DEAD);
}
return NULL;
@ -119,7 +131,7 @@ tp_tap_notify(struct tp_dispatch *tp,
assert(tp->tap.map < ARRAY_LENGTH(button_map));
if (nfingers > 3)
if (nfingers < 1 || nfingers > 3)
return;
button = button_map[tp->tap.map][nfingers - 1];
@ -211,7 +223,7 @@ tp_tap_touch_handle_event(struct tp_dispatch *tp,
1,
LIBINPUT_BUTTON_STATE_PRESSED);
if (tp->tap.drag_enabled) {
tp->tap.state = TAP_STATE_TAPPED;
tp->tap.state = TAP_STATE_1FGTAP_TAPPED;
tp->tap.saved_release_time = time;
tp_tap_set_timer(tp, time);
} else {
@ -288,30 +300,38 @@ tp_tap_hold_handle_event(struct tp_dispatch *tp,
static void
tp_tap_tapped_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
enum tap_event event, uint64_t time)
enum tap_event event, uint64_t time,
int nfingers_tapped)
{
switch (event) {
case TAP_EVENT_MOTION:
case TAP_EVENT_RELEASE:
log_tap_bug(tp, t, event);
break;
case TAP_EVENT_TOUCH:
tp->tap.state = TAP_STATE_DRAGGING_OR_DOUBLETAP;
case TAP_EVENT_TOUCH: {
enum tp_tap_state dest[3] = {
TAP_STATE_1FGTAP_DRAGGING_OR_DOUBLETAP,
TAP_STATE_2FGTAP_DRAGGING_OR_DOUBLETAP,
TAP_STATE_3FGTAP_DRAGGING_OR_DOUBLETAP,
};
assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
tp->tap.state = dest[nfingers_tapped - 1];
tp->tap.saved_press_time = time;
tp_tap_set_timer(tp, time);
break;
}
case TAP_EVENT_TIMEOUT:
tp->tap.state = TAP_STATE_IDLE;
tp_tap_notify(tp,
tp->tap.saved_release_time,
1,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
break;
case TAP_EVENT_BUTTON:
tp->tap.state = TAP_STATE_DEAD;
tp_tap_notify(tp,
tp->tap.saved_release_time,
1,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
break;
case TAP_EVENT_THUMB:
@ -353,7 +373,6 @@ tp_tap_touch2_handle_event(struct tp_dispatch *tp,
break;
case TAP_EVENT_PALM:
tp->tap.state = TAP_STATE_TOUCH;
tp_tap_set_timer(tp, time); /* overwrite timer */
break;
case TAP_EVENT_PALM_UP:
break;
@ -411,11 +430,16 @@ tp_tap_touch2_release_handle_event(struct tp_dispatch *tp,
tp->tap.saved_press_time,
2,
LIBINPUT_BUTTON_STATE_PRESSED);
tp_tap_notify(tp,
tp->tap.saved_release_time,
2,
LIBINPUT_BUTTON_STATE_RELEASED);
tp->tap.state = TAP_STATE_IDLE;
if (tp->tap.drag_enabled) {
tp->tap.state = TAP_STATE_2FGTAP_TAPPED;
tp_tap_set_timer(tp, time);
} else {
tp_tap_notify(tp,
tp->tap.saved_release_time,
2,
LIBINPUT_BUTTON_STATE_RELEASED);
tp->tap.state = TAP_STATE_IDLE;
}
break;
case TAP_EVENT_MOTION:
tp_tap_move_to_dead(tp, t);
@ -440,8 +464,7 @@ tp_tap_touch2_release_handle_event(struct tp_dispatch *tp,
1,
LIBINPUT_BUTTON_STATE_PRESSED);
if (tp->tap.drag_enabled) {
tp->tap.state = TAP_STATE_TAPPED;
tp_tap_set_timer(tp, time);
tp->tap.state = TAP_STATE_1FGTAP_TAPPED;
} else {
tp_tap_notify(tp,
tp->tap.saved_release_time,
@ -570,6 +593,14 @@ tp_tap_touch3_release_handle_event(struct tp_dispatch *tp,
tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
break;
case TAP_EVENT_BUTTON:
tp_tap_notify(tp,
tp->tap.saved_press_time,
3,
LIBINPUT_BUTTON_STATE_PRESSED);
tp_tap_notify(tp,
tp->tap.saved_release_time,
3,
LIBINPUT_BUTTON_STATE_RELEASED);
tp->tap.state = TAP_STATE_DEAD;
break;
case TAP_EVENT_THUMB:
@ -607,11 +638,16 @@ tp_tap_touch3_release2_handle_event(struct tp_dispatch *tp,
tp->tap.saved_press_time,
3,
LIBINPUT_BUTTON_STATE_PRESSED);
tp_tap_notify(tp,
tp->tap.saved_release_time,
3,
LIBINPUT_BUTTON_STATE_RELEASED);
tp->tap.state = TAP_STATE_IDLE;
if (tp->tap.drag_enabled) {
tp->tap.state = TAP_STATE_3FGTAP_TAPPED;
tp_tap_set_timer(tp, time);
} else {
tp_tap_notify(tp,
tp->tap.saved_release_time,
3,
LIBINPUT_BUTTON_STATE_RELEASED);
tp->tap.state = TAP_STATE_IDLE;
}
break;
case TAP_EVENT_MOTION:
tp_tap_notify(tp,
@ -636,6 +672,14 @@ tp_tap_touch3_release2_handle_event(struct tp_dispatch *tp,
tp->tap.state = TAP_STATE_HOLD;
break;
case TAP_EVENT_BUTTON:
tp_tap_notify(tp,
tp->tap.saved_press_time,
3,
LIBINPUT_BUTTON_STATE_PRESSED);
tp_tap_notify(tp,
tp->tap.saved_release_time,
3,
LIBINPUT_BUTTON_STATE_RELEASED);
tp->tap.state = TAP_STATE_DEAD;
break;
case TAP_EVENT_THUMB:
@ -645,11 +689,15 @@ tp_tap_touch3_release2_handle_event(struct tp_dispatch *tp,
tp->tap.saved_press_time,
2,
LIBINPUT_BUTTON_STATE_PRESSED);
tp_tap_notify(tp,
tp->tap.saved_release_time,
2,
LIBINPUT_BUTTON_STATE_RELEASED);
tp->tap.state = TAP_STATE_IDLE;
if (tp->tap.drag_enabled) {
tp->tap.state = TAP_STATE_2FGTAP_TAPPED;
} else {
tp_tap_notify(tp,
tp->tap.saved_release_time,
2,
LIBINPUT_BUTTON_STATE_RELEASED);
tp->tap.state = TAP_STATE_IDLE;
}
break;
case TAP_EVENT_PALM_UP:
break;
@ -659,17 +707,25 @@ tp_tap_touch3_release2_handle_event(struct tp_dispatch *tp,
static void
tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
enum tap_event event, uint64_t time)
enum tap_event event, uint64_t time,
int nfingers_tapped)
{
switch (event) {
case TAP_EVENT_TOUCH:
tp->tap.state = TAP_STATE_DRAGGING_2;
case TAP_EVENT_TOUCH: {
enum tp_tap_state dest[3] = {
TAP_STATE_1FGTAP_DRAGGING_2,
TAP_STATE_2FGTAP_DRAGGING_2,
TAP_STATE_3FGTAP_DRAGGING_2,
};
assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
tp->tap.state = dest[nfingers_tapped - 1];
break;
}
case TAP_EVENT_RELEASE:
tp->tap.state = TAP_STATE_TAPPED;
tp->tap.state = TAP_STATE_1FGTAP_TAPPED;
tp_tap_notify(tp,
tp->tap.saved_release_time,
1,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
tp_tap_notify(tp,
tp->tap.saved_press_time,
@ -679,21 +735,35 @@ tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp,
tp_tap_set_timer(tp, time);
break;
case TAP_EVENT_MOTION:
case TAP_EVENT_TIMEOUT:
tp->tap.state = TAP_STATE_DRAGGING;
case TAP_EVENT_TIMEOUT: {
enum tp_tap_state dest[3] = {
TAP_STATE_1FGTAP_DRAGGING,
TAP_STATE_2FGTAP_DRAGGING,
TAP_STATE_3FGTAP_DRAGGING,
};
assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
tp->tap.state = dest[nfingers_tapped - 1];
break;
}
case TAP_EVENT_BUTTON:
tp->tap.state = TAP_STATE_DEAD;
tp_tap_notify(tp,
tp->tap.saved_release_time,
1,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
break;
case TAP_EVENT_THUMB:
break;
case TAP_EVENT_PALM:
tp->tap.state = TAP_STATE_TAPPED;
case TAP_EVENT_PALM: {
enum tp_tap_state dest[3] = {
TAP_STATE_1FGTAP_TAPPED,
TAP_STATE_2FGTAP_TAPPED,
TAP_STATE_3FGTAP_TAPPED,
};
assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
tp->tap.state = dest[nfingers_tapped - 1];
break;
}
case TAP_EVENT_PALM_UP:
break;
}
@ -702,21 +772,35 @@ tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp,
static void
tp_tap_dragging_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
enum tap_event event, uint64_t time)
enum tap_event event, uint64_t time,
int nfingers_tapped)
{
switch (event) {
case TAP_EVENT_TOUCH:
tp->tap.state = TAP_STATE_DRAGGING_2;
case TAP_EVENT_TOUCH: {
enum tp_tap_state dest[3] = {
TAP_STATE_1FGTAP_DRAGGING_2,
TAP_STATE_2FGTAP_DRAGGING_2,
TAP_STATE_3FGTAP_DRAGGING_2,
};
assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
tp->tap.state = dest[nfingers_tapped - 1];
break;
}
case TAP_EVENT_RELEASE:
if (tp->tap.drag_lock_enabled) {
tp->tap.state = TAP_STATE_DRAGGING_WAIT;
enum tp_tap_state dest[3] = {
TAP_STATE_1FGTAP_DRAGGING_WAIT,
TAP_STATE_2FGTAP_DRAGGING_WAIT,
TAP_STATE_3FGTAP_DRAGGING_WAIT,
};
assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
tp->tap.state = dest[nfingers_tapped - 1];
tp_tap_set_drag_timer(tp, time);
} else {
tp_tap_notify(tp,
time,
1,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
tp->tap.state = TAP_STATE_IDLE;
}
@ -727,14 +811,17 @@ tp_tap_dragging_handle_event(struct tp_dispatch *tp,
break;
case TAP_EVENT_BUTTON:
tp->tap.state = TAP_STATE_DEAD;
tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
tp_tap_notify(tp,
time,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
break;
case TAP_EVENT_THUMB:
break;
case TAP_EVENT_PALM:
tp_tap_notify(tp,
tp->tap.saved_release_time,
1,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
tp->tap.state = TAP_STATE_IDLE;
break;
@ -746,24 +833,38 @@ tp_tap_dragging_handle_event(struct tp_dispatch *tp,
static void
tp_tap_dragging_wait_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
enum tap_event event, uint64_t time)
enum tap_event event, uint64_t time,
int nfingers_tapped)
{
switch (event) {
case TAP_EVENT_TOUCH:
tp->tap.state = TAP_STATE_DRAGGING_OR_TAP;
case TAP_EVENT_TOUCH: {
enum tp_tap_state dest[3] = {
TAP_STATE_1FGTAP_DRAGGING_OR_TAP,
TAP_STATE_2FGTAP_DRAGGING_OR_TAP,
TAP_STATE_3FGTAP_DRAGGING_OR_TAP,
};
assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
tp->tap.state = dest[nfingers_tapped - 1];
tp_tap_set_timer(tp, time);
break;
}
case TAP_EVENT_RELEASE:
case TAP_EVENT_MOTION:
break;
case TAP_EVENT_TIMEOUT:
tp->tap.state = TAP_STATE_IDLE;
tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
tp_tap_notify(tp,
time,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
break;
case TAP_EVENT_BUTTON:
tp->tap.state = TAP_STATE_DEAD;
tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
tp_tap_notify(tp,
time,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
break;
case TAP_EVENT_THUMB:
case TAP_EVENT_PALM:
@ -776,35 +877,56 @@ tp_tap_dragging_wait_handle_event(struct tp_dispatch *tp,
static void
tp_tap_dragging_tap_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
enum tap_event event, uint64_t time)
enum tap_event event, uint64_t time,
int nfingers_tapped)
{
switch (event) {
case TAP_EVENT_TOUCH:
tp->tap.state = TAP_STATE_DRAGGING_2;
tp_tap_clear_timer(tp);
case TAP_EVENT_TOUCH: {
enum tp_tap_state dest[3] = {
TAP_STATE_1FGTAP_DRAGGING_2,
TAP_STATE_2FGTAP_DRAGGING_2,
TAP_STATE_3FGTAP_DRAGGING_2,
};
assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
tp->tap.state = dest[nfingers_tapped - 1];
break;
}
case TAP_EVENT_RELEASE:
tp->tap.state = TAP_STATE_IDLE;
tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
tp_tap_notify(tp,
time,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
break;
case TAP_EVENT_MOTION:
case TAP_EVENT_TIMEOUT:
tp->tap.state = TAP_STATE_DRAGGING;
case TAP_EVENT_TIMEOUT: {
enum tp_tap_state dest[3] = {
TAP_STATE_1FGTAP_DRAGGING,
TAP_STATE_2FGTAP_DRAGGING,
TAP_STATE_3FGTAP_DRAGGING,
};
assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
tp->tap.state = dest[nfingers_tapped - 1];
break;
}
case TAP_EVENT_BUTTON:
tp->tap.state = TAP_STATE_DEAD;
tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
tp_tap_notify(tp,
time,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
break;
case TAP_EVENT_THUMB:
break;
case TAP_EVENT_PALM:
tp_tap_notify(tp,
tp->tap.saved_release_time,
1,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
tp->tap.state = TAP_STATE_IDLE;
break;
}
case TAP_EVENT_PALM_UP:
break;
}
@ -813,16 +935,27 @@ tp_tap_dragging_tap_handle_event(struct tp_dispatch *tp,
static void
tp_tap_dragging2_handle_event(struct tp_dispatch *tp,
struct tp_touch *t,
enum tap_event event, uint64_t time)
enum tap_event event, uint64_t time,
int nfingers_tapped)
{
switch (event) {
case TAP_EVENT_RELEASE:
tp->tap.state = TAP_STATE_DRAGGING;
case TAP_EVENT_RELEASE: {
enum tp_tap_state dest[3] = {
TAP_STATE_1FGTAP_DRAGGING,
TAP_STATE_2FGTAP_DRAGGING,
TAP_STATE_3FGTAP_DRAGGING,
};
assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
tp->tap.state = dest[nfingers_tapped - 1];
break;
}
case TAP_EVENT_TOUCH:
tp->tap.state = TAP_STATE_DEAD;
tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
tp_tap_notify(tp,
time,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
break;
case TAP_EVENT_MOTION:
case TAP_EVENT_TIMEOUT:
@ -830,13 +963,23 @@ tp_tap_dragging2_handle_event(struct tp_dispatch *tp,
break;
case TAP_EVENT_BUTTON:
tp->tap.state = TAP_STATE_DEAD;
tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
tp_tap_notify(tp,
time,
nfingers_tapped,
LIBINPUT_BUTTON_STATE_RELEASED);
break;
case TAP_EVENT_THUMB:
break;
case TAP_EVENT_PALM:
tp->tap.state = TAP_STATE_DRAGGING_OR_DOUBLETAP;
case TAP_EVENT_PALM: {
enum tp_tap_state dest[3] = {
TAP_STATE_1FGTAP_DRAGGING_OR_DOUBLETAP,
TAP_STATE_2FGTAP_DRAGGING_OR_DOUBLETAP,
TAP_STATE_3FGTAP_DRAGGING_OR_DOUBLETAP,
};
assert(nfingers_tapped >= 1 && nfingers_tapped <= 3);
tp->tap.state = dest[nfingers_tapped - 1];
break;
}
case TAP_EVENT_PALM_UP:
break;
}
@ -889,8 +1032,14 @@ tp_tap_handle_event(struct tp_dispatch *tp,
case TAP_STATE_HOLD:
tp_tap_hold_handle_event(tp, t, event, time);
break;
case TAP_STATE_TAPPED:
tp_tap_tapped_handle_event(tp, t, event, time);
case TAP_STATE_1FGTAP_TAPPED:
tp_tap_tapped_handle_event(tp, t, event, time, 1);
break;
case TAP_STATE_2FGTAP_TAPPED:
tp_tap_tapped_handle_event(tp, t, event, time, 2);
break;
case TAP_STATE_3FGTAP_TAPPED:
tp_tap_tapped_handle_event(tp, t, event, time, 3);
break;
case TAP_STATE_TOUCH_2:
tp_tap_touch2_handle_event(tp, t, event, time);
@ -913,20 +1062,53 @@ tp_tap_handle_event(struct tp_dispatch *tp,
case TAP_STATE_TOUCH_3_RELEASE_2:
tp_tap_touch3_release2_handle_event(tp, t, event, time);
break;
case TAP_STATE_DRAGGING_OR_DOUBLETAP:
tp_tap_dragging_or_doubletap_handle_event(tp, t, event, time);
case TAP_STATE_1FGTAP_DRAGGING_OR_DOUBLETAP:
tp_tap_dragging_or_doubletap_handle_event(tp, t, event, time,
1);
break;
case TAP_STATE_DRAGGING:
tp_tap_dragging_handle_event(tp, t, event, time);
case TAP_STATE_2FGTAP_DRAGGING_OR_DOUBLETAP:
tp_tap_dragging_or_doubletap_handle_event(tp, t, event, time,
2);
break;
case TAP_STATE_DRAGGING_WAIT:
tp_tap_dragging_wait_handle_event(tp, t, event, time);
case TAP_STATE_3FGTAP_DRAGGING_OR_DOUBLETAP:
tp_tap_dragging_or_doubletap_handle_event(tp, t, event, time,
3);
break;
case TAP_STATE_DRAGGING_OR_TAP:
tp_tap_dragging_tap_handle_event(tp, t, event, time);
case TAP_STATE_1FGTAP_DRAGGING:
tp_tap_dragging_handle_event(tp, t, event, time, 1);
break;
case TAP_STATE_DRAGGING_2:
tp_tap_dragging2_handle_event(tp, t, event, time);
case TAP_STATE_2FGTAP_DRAGGING:
tp_tap_dragging_handle_event(tp, t, event, time, 2);
break;
case TAP_STATE_3FGTAP_DRAGGING:
tp_tap_dragging_handle_event(tp, t, event, time, 3);
break;
case TAP_STATE_1FGTAP_DRAGGING_WAIT:
tp_tap_dragging_wait_handle_event(tp, t, event, time, 1);
break;
case TAP_STATE_2FGTAP_DRAGGING_WAIT:
tp_tap_dragging_wait_handle_event(tp, t, event, time, 2);
break;
case TAP_STATE_3FGTAP_DRAGGING_WAIT:
tp_tap_dragging_wait_handle_event(tp, t, event, time, 3);
break;
case TAP_STATE_1FGTAP_DRAGGING_OR_TAP:
tp_tap_dragging_tap_handle_event(tp, t, event, time, 1);
break;
case TAP_STATE_2FGTAP_DRAGGING_OR_TAP:
tp_tap_dragging_tap_handle_event(tp, t, event, time, 2);
break;
case TAP_STATE_3FGTAP_DRAGGING_OR_TAP:
tp_tap_dragging_tap_handle_event(tp, t, event, time, 3);
break;
case TAP_STATE_1FGTAP_DRAGGING_2:
tp_tap_dragging2_handle_event(tp, t, event, time, 1);
break;
case TAP_STATE_2FGTAP_DRAGGING_2:
tp_tap_dragging2_handle_event(tp, t, event, time, 2);
break;
case TAP_STATE_3FGTAP_DRAGGING_2:
tp_tap_dragging2_handle_event(tp, t, event, time, 3);
break;
case TAP_STATE_DEAD:
tp_tap_dead_handle_event(tp, t, event, time);
@ -1090,9 +1272,15 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time)
*/
switch (tp->tap.state) {
case TAP_STATE_TOUCH:
case TAP_STATE_TAPPED:
case TAP_STATE_DRAGGING_OR_DOUBLETAP:
case TAP_STATE_DRAGGING_OR_TAP:
case TAP_STATE_1FGTAP_TAPPED:
case TAP_STATE_2FGTAP_TAPPED:
case TAP_STATE_3FGTAP_TAPPED:
case TAP_STATE_1FGTAP_DRAGGING_OR_DOUBLETAP:
case TAP_STATE_2FGTAP_DRAGGING_OR_DOUBLETAP:
case TAP_STATE_3FGTAP_DRAGGING_OR_DOUBLETAP:
case TAP_STATE_1FGTAP_DRAGGING_OR_TAP:
case TAP_STATE_2FGTAP_DRAGGING_OR_TAP:
case TAP_STATE_3FGTAP_DRAGGING_OR_TAP:
case TAP_STATE_TOUCH_2:
case TAP_STATE_TOUCH_3:
filter_motion = 1;
@ -1421,10 +1609,18 @@ bool
tp_tap_dragging(const struct tp_dispatch *tp)
{
switch (tp->tap.state) {
case TAP_STATE_DRAGGING:
case TAP_STATE_DRAGGING_2:
case TAP_STATE_DRAGGING_WAIT:
case TAP_STATE_DRAGGING_OR_TAP:
case TAP_STATE_1FGTAP_DRAGGING:
case TAP_STATE_2FGTAP_DRAGGING:
case TAP_STATE_3FGTAP_DRAGGING:
case TAP_STATE_1FGTAP_DRAGGING_2:
case TAP_STATE_2FGTAP_DRAGGING_2:
case TAP_STATE_3FGTAP_DRAGGING_2:
case TAP_STATE_1FGTAP_DRAGGING_WAIT:
case TAP_STATE_2FGTAP_DRAGGING_WAIT:
case TAP_STATE_3FGTAP_DRAGGING_WAIT:
case TAP_STATE_1FGTAP_DRAGGING_OR_TAP:
case TAP_STATE_2FGTAP_DRAGGING_OR_TAP:
case TAP_STATE_3FGTAP_DRAGGING_OR_TAP:
return true;
default:
return false;

View file

@ -106,7 +106,9 @@ enum tp_tap_state {
TAP_STATE_IDLE = 4,
TAP_STATE_TOUCH,
TAP_STATE_HOLD,
TAP_STATE_TAPPED,
TAP_STATE_1FGTAP_TAPPED,
TAP_STATE_2FGTAP_TAPPED,
TAP_STATE_3FGTAP_TAPPED,
TAP_STATE_TOUCH_2,
TAP_STATE_TOUCH_2_HOLD,
TAP_STATE_TOUCH_2_RELEASE,
@ -114,11 +116,21 @@ enum tp_tap_state {
TAP_STATE_TOUCH_3_HOLD,
TAP_STATE_TOUCH_3_RELEASE,
TAP_STATE_TOUCH_3_RELEASE_2,
TAP_STATE_DRAGGING_OR_DOUBLETAP,
TAP_STATE_DRAGGING_OR_TAP,
TAP_STATE_DRAGGING,
TAP_STATE_DRAGGING_WAIT,
TAP_STATE_DRAGGING_2,
TAP_STATE_1FGTAP_DRAGGING_OR_DOUBLETAP,
TAP_STATE_2FGTAP_DRAGGING_OR_DOUBLETAP,
TAP_STATE_3FGTAP_DRAGGING_OR_DOUBLETAP,
TAP_STATE_1FGTAP_DRAGGING_OR_TAP,
TAP_STATE_2FGTAP_DRAGGING_OR_TAP,
TAP_STATE_3FGTAP_DRAGGING_OR_TAP,
TAP_STATE_1FGTAP_DRAGGING,
TAP_STATE_2FGTAP_DRAGGING,
TAP_STATE_3FGTAP_DRAGGING,
TAP_STATE_1FGTAP_DRAGGING_WAIT,
TAP_STATE_2FGTAP_DRAGGING_WAIT,
TAP_STATE_3FGTAP_DRAGGING_WAIT,
TAP_STATE_1FGTAP_DRAGGING_2,
TAP_STATE_2FGTAP_DRAGGING_2,
TAP_STATE_3FGTAP_DRAGGING_2,
TAP_STATE_DEAD, /**< finger count exceeded */
};

View file

@ -4560,10 +4560,9 @@ enum libinput_config_drag_state {
* @ingroup config
*
* Enable or disable tap-and-drag on this device. When enabled, a
* single-finger tap immediately followed by a finger down results in a
* button down event, subsequent finger motion thus triggers a drag. The
* button is released on finger up. See the libinput documentation for more
* details.
* tap immediately followed by a finger down results in a button down event,
* subsequent finger motion thus triggers a drag. The button is released
* on finger up. See the libinput documentation for more details.
*
* @param device The device to configure
* @param enable @ref LIBINPUT_CONFIG_DRAG_ENABLED to enable, @ref

View file

@ -1048,6 +1048,8 @@ START_TEST(touchpad_2fg_tap)
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
libinput_dispatch(li);
litest_timeout_tap();
libinput_dispatch(li);
ev = libinput_get_event(li);
@ -1100,6 +1102,8 @@ START_TEST(touchpad_2fg_tap_inverted)
litest_touch_up(dev, 1);
litest_touch_up(dev, 0);
libinput_dispatch(li);
litest_timeout_tap();
libinput_dispatch(li);
ev = libinput_get_event(li);
@ -1557,6 +1561,8 @@ START_TEST(touchpad_3fg_tap)
litest_touch_up(dev, (i + 1) % 3);
litest_touch_up(dev, (i + 0) % 3);
libinput_dispatch(li);
litest_timeout_tap();
libinput_dispatch(li);
ev = libinput_get_event(li);
@ -1609,6 +1615,8 @@ START_TEST(touchpad_3fg_tap_tap_again)
litest_touch_up(dev, 1);
litest_touch_up(dev, 2);
libinput_dispatch(li);
litest_timeout_tap();
libinput_dispatch(li);
for (i = 0; i < 2; i++) {