mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-03 20:30:27 +01:00
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:
parent
5e6d03ff19
commit
0e569077fe
4 changed files with 313 additions and 98 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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++) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue