mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-05 00:30:26 +01:00
touchpad: send multitap button events with the correct timestamps
For multitap, we're one tap behind with the button clicks, i.e. we send the first full click button on the second tap, etc. Remember the timestamps of the touches so we can send the events with the right timestamps. This makes tapping more accurate because the time between taps and various timeouts matter less for double-click detection. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
68ed1b96a8
commit
4c0b8ba4c2
3 changed files with 105 additions and 17 deletions
|
|
@ -152,7 +152,7 @@ tp_tap_idle_handle_event(struct tp_dispatch *tp,
|
|||
switch (event) {
|
||||
case TAP_EVENT_TOUCH:
|
||||
tp->tap.state = TAP_STATE_TOUCH;
|
||||
tp->tap.first_press_time = time;
|
||||
tp->tap.saved_press_time = time;
|
||||
tp_tap_set_timer(tp, time);
|
||||
break;
|
||||
case TAP_EVENT_RELEASE:
|
||||
|
|
@ -186,11 +186,12 @@ tp_tap_touch_handle_event(struct tp_dispatch *tp,
|
|||
break;
|
||||
case TAP_EVENT_RELEASE:
|
||||
tp_tap_notify(tp,
|
||||
tp->tap.first_press_time,
|
||||
tp->tap.saved_press_time,
|
||||
1,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
if (tp->tap.drag_enabled) {
|
||||
tp->tap.state = TAP_STATE_TAPPED;
|
||||
tp->tap.saved_release_time = time;
|
||||
tp_tap_set_timer(tp, time);
|
||||
} else {
|
||||
tp_tap_notify(tp,
|
||||
|
|
@ -258,15 +259,22 @@ tp_tap_tapped_handle_event(struct tp_dispatch *tp,
|
|||
break;
|
||||
case TAP_EVENT_TOUCH:
|
||||
tp->tap.state = TAP_STATE_DRAGGING_OR_DOUBLETAP;
|
||||
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, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
tp_tap_notify(tp,
|
||||
tp->tap.saved_release_time,
|
||||
1,
|
||||
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,
|
||||
tp->tap.saved_release_time,
|
||||
1,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
break;
|
||||
case TAP_EVENT_THUMB:
|
||||
break;
|
||||
|
|
@ -342,7 +350,7 @@ tp_tap_touch2_release_handle_event(struct tp_dispatch *tp,
|
|||
break;
|
||||
case TAP_EVENT_RELEASE:
|
||||
tp_tap_notify(tp,
|
||||
tp->tap.first_press_time,
|
||||
tp->tap.saved_press_time,
|
||||
2,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
tp_tap_notify(tp, time, 2, LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
|
|
@ -380,7 +388,7 @@ tp_tap_touch3_handle_event(struct tp_dispatch *tp,
|
|||
tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
|
||||
if (t->tap.state == TAP_TOUCH_STATE_TOUCH) {
|
||||
tp_tap_notify(tp,
|
||||
tp->tap.first_press_time,
|
||||
tp->tap.saved_press_time,
|
||||
3,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
tp_tap_notify(tp, time, 3, LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
|
|
@ -430,7 +438,11 @@ tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp,
|
|||
break;
|
||||
case TAP_EVENT_RELEASE:
|
||||
tp->tap.state = TAP_STATE_MULTITAP;
|
||||
tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
tp_tap_notify(tp,
|
||||
tp->tap.saved_release_time,
|
||||
1,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
tp->tap.saved_release_time = time;
|
||||
break;
|
||||
case TAP_EVENT_MOTION:
|
||||
case TAP_EVENT_TIMEOUT:
|
||||
|
|
@ -438,7 +450,10 @@ tp_tap_dragging_or_doubletap_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,
|
||||
tp->tap.saved_release_time,
|
||||
1,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
break;
|
||||
case TAP_EVENT_THUMB:
|
||||
break;
|
||||
|
|
@ -574,7 +589,11 @@ tp_tap_multitap_handle_event(struct tp_dispatch *tp,
|
|||
break;
|
||||
case TAP_EVENT_TOUCH:
|
||||
tp->tap.state = TAP_STATE_MULTITAP_DOWN;
|
||||
tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
tp_tap_notify(tp,
|
||||
tp->tap.saved_press_time,
|
||||
1,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
tp->tap.saved_press_time = time;
|
||||
tp_tap_set_timer(tp, time);
|
||||
break;
|
||||
case TAP_EVENT_MOTION:
|
||||
|
|
@ -583,8 +602,14 @@ tp_tap_multitap_handle_event(struct tp_dispatch *tp,
|
|||
break;
|
||||
case TAP_EVENT_TIMEOUT:
|
||||
tp->tap.state = TAP_STATE_IDLE;
|
||||
tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
tp_tap_notify(tp,
|
||||
tp->tap.saved_press_time,
|
||||
1,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
tp_tap_notify(tp,
|
||||
tp->tap.saved_release_time,
|
||||
1,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
break;
|
||||
case TAP_EVENT_BUTTON:
|
||||
tp->tap.state = TAP_STATE_IDLE;
|
||||
|
|
@ -604,7 +629,11 @@ tp_tap_multitap_down_handle_event(struct tp_dispatch *tp,
|
|||
switch (event) {
|
||||
case TAP_EVENT_RELEASE:
|
||||
tp->tap.state = TAP_STATE_MULTITAP;
|
||||
tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
tp_tap_notify(tp,
|
||||
tp->tap.saved_release_time,
|
||||
1,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
tp->tap.saved_release_time = time;
|
||||
break;
|
||||
case TAP_EVENT_TOUCH:
|
||||
tp->tap.state = TAP_STATE_DRAGGING_2;
|
||||
|
|
@ -617,7 +646,10 @@ tp_tap_multitap_down_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,
|
||||
tp->tap.saved_release_time,
|
||||
1,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
tp_tap_clear_timer(tp);
|
||||
break;
|
||||
case TAP_EVENT_THUMB:
|
||||
|
|
|
|||
|
|
@ -321,7 +321,8 @@ struct tp_dispatch {
|
|||
struct libinput_timer timer;
|
||||
enum tp_tap_state state;
|
||||
uint32_t buttons_pressed;
|
||||
uint64_t first_press_time;
|
||||
uint64_t saved_press_time,
|
||||
saved_release_time;
|
||||
|
||||
enum libinput_config_tap_button_map map;
|
||||
enum libinput_config_tap_button_map want_map;
|
||||
|
|
|
|||
|
|
@ -69,8 +69,11 @@ START_TEST(touchpad_1fg_doubletap)
|
|||
litest_drain_events(li);
|
||||
|
||||
litest_touch_down(dev, 0, 50, 50);
|
||||
msleep(10);
|
||||
litest_touch_up(dev, 0);
|
||||
msleep(10);
|
||||
litest_touch_down(dev, 0, 50, 50);
|
||||
msleep(10);
|
||||
litest_touch_up(dev, 0);
|
||||
libinput_dispatch(li);
|
||||
|
||||
|
|
@ -90,7 +93,7 @@ START_TEST(touchpad_1fg_doubletap)
|
|||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
curtime = libinput_event_pointer_get_time(ptrev);
|
||||
libinput_event_destroy(event);
|
||||
ck_assert_int_le(oldtime, curtime);
|
||||
ck_assert_int_lt(oldtime, curtime);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
ptrev = litest_is_button_event(event,
|
||||
|
|
@ -107,7 +110,7 @@ START_TEST(touchpad_1fg_doubletap)
|
|||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
curtime = libinput_event_pointer_get_time(ptrev);
|
||||
libinput_event_destroy(event);
|
||||
ck_assert_int_le(oldtime, curtime);
|
||||
ck_assert_int_lt(oldtime, curtime);
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
|
|
@ -365,6 +368,54 @@ START_TEST(touchpad_1fg_multitap_n_drag_click)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_1fg_multitap_timeout)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
struct libinput_event *event;
|
||||
struct libinput_event_pointer *ptrev;
|
||||
uint32_t ptime, rtime;
|
||||
int range = _i, /* looped test */
|
||||
ntaps;
|
||||
|
||||
litest_enable_tap(dev->libinput_device);
|
||||
litest_enable_drag_lock(dev->libinput_device);
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
for (ntaps = 0; ntaps <= range; ntaps++) {
|
||||
litest_touch_down(dev, 0, 50, 50);
|
||||
msleep(10);
|
||||
litest_touch_up(dev, 0);
|
||||
libinput_dispatch(li);
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
libinput_dispatch(li);
|
||||
litest_timeout_tap();
|
||||
libinput_dispatch(li);
|
||||
|
||||
for (ntaps = 0; ntaps <= range; ntaps++) {
|
||||
event = libinput_get_event(li);
|
||||
ptrev = litest_is_button_event(event,
|
||||
BTN_LEFT,
|
||||
LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
ptime = libinput_event_pointer_get_time(ptrev);
|
||||
libinput_event_destroy(event);
|
||||
|
||||
event = libinput_get_event(li);
|
||||
ptrev = litest_is_button_event(event,
|
||||
BTN_LEFT,
|
||||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
rtime = libinput_event_pointer_get_time(ptrev);
|
||||
libinput_event_destroy(event);
|
||||
ck_assert_int_lt(ptime, rtime);
|
||||
}
|
||||
|
||||
litest_assert_empty_queue(li);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(touchpad_1fg_multitap_n_drag_timeout)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
|
|
@ -383,6 +434,7 @@ START_TEST(touchpad_1fg_multitap_n_drag_timeout)
|
|||
|
||||
for (ntaps = 0; ntaps <= range; ntaps++) {
|
||||
litest_touch_down(dev, 0, 50, 50);
|
||||
msleep(10);
|
||||
litest_touch_up(dev, 0);
|
||||
libinput_dispatch(li);
|
||||
msleep(10);
|
||||
|
|
@ -410,7 +462,7 @@ START_TEST(touchpad_1fg_multitap_n_drag_timeout)
|
|||
LIBINPUT_BUTTON_STATE_RELEASED);
|
||||
curtime = libinput_event_pointer_get_time(ptrev);
|
||||
libinput_event_destroy(event);
|
||||
ck_assert_int_ge(curtime, oldtime);
|
||||
ck_assert_int_gt(curtime, oldtime);
|
||||
oldtime = curtime;
|
||||
}
|
||||
|
||||
|
|
@ -454,6 +506,7 @@ START_TEST(touchpad_1fg_multitap_n_drag_tap)
|
|||
|
||||
for (ntaps = 0; ntaps <= range; ntaps++) {
|
||||
litest_touch_down(dev, 0, 50, 50);
|
||||
msleep(10);
|
||||
litest_touch_up(dev, 0);
|
||||
libinput_dispatch(li);
|
||||
msleep(10);
|
||||
|
|
@ -527,6 +580,7 @@ START_TEST(touchpad_1fg_multitap_n_drag_tap_click)
|
|||
|
||||
for (ntaps = 0; ntaps <= range; ntaps++) {
|
||||
litest_touch_down(dev, 0, 50, 50);
|
||||
msleep(10);
|
||||
litest_touch_up(dev, 0);
|
||||
libinput_dispatch(li);
|
||||
msleep(10);
|
||||
|
|
@ -2223,6 +2277,7 @@ litest_setup_tests_touchpad_tap(void)
|
|||
litest_add("tap-1fg:1fg", touchpad_1fg_tap, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add("tap-1fg:1fg", touchpad_1fg_doubletap, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add_ranged("tap-multitap:1fg", touchpad_1fg_multitap, LITEST_TOUCHPAD, LITEST_ANY, &multitap_range);
|
||||
litest_add_ranged("tap-multitap:1fg", touchpad_1fg_multitap_timeout, LITEST_TOUCHPAD, LITEST_ANY, &multitap_range);
|
||||
litest_add_ranged("tap-multitap:1fg", touchpad_1fg_multitap_n_drag_timeout, LITEST_TOUCHPAD, LITEST_ANY, &multitap_range);
|
||||
litest_add_ranged("tap-multitap:1fg", touchpad_1fg_multitap_n_drag_tap, LITEST_TOUCHPAD, LITEST_ANY, &multitap_range);
|
||||
litest_add_ranged("tap-multitap:1fg", touchpad_1fg_multitap_n_drag_move, LITEST_TOUCHPAD, LITEST_ANY, &multitap_range);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue