From 00f74270e5c28e02a3e4fcbbc5d34770aff3911b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 25 Sep 2014 13:20:47 +0200 Subject: [PATCH 1/7] litest: Add a sleep_ms parameter to litest_touch_move_to In reality moving a touch from point to another takes time. In some cases (when a timeout may trigger during the move, e.g. tap-n-drag on a touchpad), this is important. Add a sleep_ms parameter, which will cause litest_touch_move_to to sleep the specified amount of ms every step. Signed-off-by: Hans de Goede --- test/device.c | 2 +- test/litest.c | 10 +++++++-- test/litest.h | 2 +- test/touchpad.c | 56 ++++++++++++++++++++++++------------------------- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/test/device.c b/test/device.c index 0a53661e..1faa2edf 100644 --- a/test/device.c +++ b/test/device.c @@ -131,7 +131,7 @@ START_TEST(device_disable_touchpad) litest_assert_empty_queue(li); litest_touch_down(dev, 0, 50, 50); - litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10); + litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10, 0); litest_touch_up(dev, 0); diff --git a/test/litest.c b/test/litest.c index b7866714..dc6a6306 100644 --- a/test/litest.c +++ b/test/litest.c @@ -762,12 +762,18 @@ litest_touch_move_to(struct litest_device *d, unsigned int slot, double x_from, double y_from, double x_to, double y_to, - int steps) + int steps, int sleep_ms) { - for (int i = 0; i < steps - 1; i++) + for (int i = 0; i < steps - 1; i++) { litest_touch_move(d, slot, x_from + (x_to - x_from)/steps * i, y_from + (y_to - y_from)/steps * i); + if (sleep_ms) { + libinput_dispatch(d->libinput); + msleep(sleep_ms); + libinput_dispatch(d->libinput); + } + } litest_touch_move(d, slot, x_to, y_to); } diff --git a/test/litest.h b/test/litest.h index 85755567..173d0f4f 100644 --- a/test/litest.h +++ b/test/litest.h @@ -136,7 +136,7 @@ void litest_touch_move_to(struct litest_device *d, unsigned int slot, double x_from, double y_from, double x_to, double y_to, - int steps); + int steps, int sleep_ms); void litest_button_click(struct litest_device *d, unsigned int button, bool is_press); diff --git a/test/touchpad.c b/test/touchpad.c index 8cd838e7..576f9ffa 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -41,7 +41,7 @@ START_TEST(touchpad_1fg_motion) litest_drain_events(li); litest_touch_down(dev, 0, 50, 50); - litest_touch_move_to(dev, 0, 50, 50, 80, 50, 5); + litest_touch_move_to(dev, 0, 50, 50, 80, 50, 5, 0); litest_touch_up(dev, 0); libinput_dispatch(li); @@ -72,8 +72,8 @@ START_TEST(touchpad_2fg_no_motion) litest_touch_down(dev, 0, 20, 20); litest_touch_down(dev, 1, 70, 20); - litest_touch_move_to(dev, 0, 20, 20, 80, 80, 5); - litest_touch_move_to(dev, 1, 70, 20, 80, 50, 5); + litest_touch_move_to(dev, 0, 20, 20, 80, 80, 5, 0); + litest_touch_move_to(dev, 1, 70, 20, 80, 50, 5, 0); litest_touch_up(dev, 1); litest_touch_up(dev, 0); @@ -131,7 +131,7 @@ START_TEST(touchpad_1fg_tap_n_drag) litest_touch_down(dev, 0, 50, 50); litest_touch_up(dev, 0); litest_touch_down(dev, 0, 50, 50); - litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5); + litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 0); litest_touch_up(dev, 0); libinput_dispatch(li); @@ -150,7 +150,7 @@ START_TEST(touchpad_1fg_tap_n_drag) /* lift finger, set down again, should continue dragging */ litest_touch_down(dev, 0, 50, 50); - litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5); + litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 0); litest_touch_up(dev, 0); libinput_dispatch(li); @@ -400,7 +400,7 @@ START_TEST(touchpad_no_2fg_tap_after_move) -> no event */ litest_touch_down(dev, 0, 50, 50); - litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10); + litest_touch_move_to(dev, 0, 50, 50, 90, 90, 10, 0); litest_drain_events(dev->libinput); litest_touch_down(dev, 1, 70, 50); @@ -450,7 +450,7 @@ START_TEST(touchpad_no_first_fg_tap_after_move) litest_touch_down(dev, 0, 50, 50); litest_touch_down(dev, 1, 70, 50); libinput_dispatch(dev->libinput); - litest_touch_move_to(dev, 1, 70, 50, 90, 90, 10); + litest_touch_move_to(dev, 1, 70, 50, 90, 90, 10, 0); libinput_dispatch(dev->libinput); litest_touch_up(dev, 0); litest_touch_up(dev, 1); @@ -516,7 +516,7 @@ START_TEST(touchpad_1fg_tap_n_drag_click) litest_touch_down(dev, 0, 50, 50); litest_touch_up(dev, 0); litest_touch_down(dev, 0, 50, 50); - litest_touch_move_to(dev, 0, 50, 50, 80, 50, 10); + litest_touch_move_to(dev, 0, 50, 50, 80, 50, 10, 0); litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED); @@ -803,7 +803,7 @@ START_TEST(clickpad_click_n_drag) /* now put a second finger down */ litest_touch_down(dev, 1, 70, 70); - litest_touch_move_to(dev, 1, 70, 70, 80, 50, 5); + litest_touch_move_to(dev, 1, 70, 70, 80, 50, 5, 0); litest_touch_up(dev, 1); libinput_dispatch(li); @@ -997,14 +997,14 @@ START_TEST(clickpad_softbutton_left_1st_fg_move) litest_assert_empty_queue(li); /* move out of the area, then wait for softbutton timer */ - litest_touch_move_to(dev, 0, 20, 90, 90, 20, 10); + litest_touch_move_to(dev, 0, 20, 90, 90, 20, 10, 0); libinput_dispatch(li); litest_timeout_softbuttons(); libinput_dispatch(li); litest_drain_events(li); /* move down left, expect motion */ - litest_touch_move_to(dev, 0, 90, 20, 20, 90, 10); + litest_touch_move_to(dev, 0, 90, 20, 20, 90, 10, 0); libinput_dispatch(li); event = libinput_get_event(li); @@ -1070,7 +1070,7 @@ START_TEST(clickpad_softbutton_left_2nd_fg_move) litest_assert_empty_queue(li); litest_touch_down(dev, 1, 20, 20); - litest_touch_move_to(dev, 1, 20, 20, 80, 20, 10); + litest_touch_move_to(dev, 1, 20, 20, 80, 20, 10, 0); libinput_dispatch(li); event = libinput_get_event(li); @@ -1097,7 +1097,7 @@ START_TEST(clickpad_softbutton_left_2nd_fg_move) /* second finger down */ litest_touch_down(dev, 1, 20, 20); - litest_touch_move_to(dev, 1, 20, 20, 20, 80, 10); + litest_touch_move_to(dev, 1, 20, 20, 20, 80, 10, 0); libinput_dispatch(li); event = libinput_get_event(li); @@ -1148,7 +1148,7 @@ START_TEST(clickpad_softbutton_left_to_right) */ litest_touch_down(dev, 0, 20, 90); - litest_touch_move_to(dev, 0, 20, 90, 90, 90, 10); + litest_touch_move_to(dev, 0, 20, 90, 90, 90, 10, 0); litest_event(dev, EV_KEY, BTN_LEFT, 1); litest_event(dev, EV_SYN, SYN_REPORT, 0); @@ -1182,7 +1182,7 @@ START_TEST(clickpad_softbutton_right_to_left) */ litest_touch_down(dev, 0, 90, 90); - litest_touch_move_to(dev, 0, 90, 90, 20, 90, 10); + litest_touch_move_to(dev, 0, 90, 90, 20, 90, 10, 0); litest_event(dev, EV_KEY, BTN_LEFT, 1); litest_event(dev, EV_SYN, SYN_REPORT, 0); @@ -1306,7 +1306,7 @@ START_TEST(clickpad_topsoftbuttons_move_out_ignore) libinput_dispatch(li); litest_assert_empty_queue(li); - litest_touch_move_to(dev, 0, 50, 5, 80, 90, 20); + litest_touch_move_to(dev, 0, 50, 5, 80, 90, 20, 0); libinput_dispatch(li); litest_timeout_softbuttons(); libinput_dispatch(li); @@ -1330,8 +1330,8 @@ test_2fg_scroll(struct litest_device *dev, double dx, double dy, int want_sleep) litest_touch_down(dev, 0, 47, 50); litest_touch_down(dev, 1, 53, 50); - litest_touch_move_to(dev, 0, 47, 50, 47 + dx, 50 + dy, 5); - litest_touch_move_to(dev, 1, 53, 50, 53 + dx, 50 + dy, 5); + litest_touch_move_to(dev, 0, 47, 50, 47 + dx, 50 + dy, 5, 0); + litest_touch_move_to(dev, 1, 53, 50, 53 + dx, 50 + dy, 5, 0); /* Avoid a small scroll being seen as a tap */ if (want_sleep) { @@ -1482,13 +1482,13 @@ START_TEST(touchpad_palm_detect_at_edge) litest_drain_events(li); litest_touch_down(dev, 0, 99, 50); - litest_touch_move_to(dev, 0, 99, 50, 99, 70, 5); + litest_touch_move_to(dev, 0, 99, 50, 99, 70, 5, 0); litest_touch_up(dev, 0); litest_assert_empty_queue(li); litest_touch_down(dev, 0, 5, 50); - litest_touch_move_to(dev, 0, 5, 50, 5, 70, 5); + litest_touch_move_to(dev, 0, 5, 50, 5, 70, 5, 0); litest_touch_up(dev, 0); } END_TEST @@ -1506,13 +1506,13 @@ START_TEST(touchpad_palm_detect_at_bottom_corners) litest_drain_events(li); litest_touch_down(dev, 0, 99, 95); - litest_touch_move_to(dev, 0, 99, 95, 99, 99, 10); + litest_touch_move_to(dev, 0, 99, 95, 99, 99, 10, 0); litest_touch_up(dev, 0); litest_assert_empty_queue(li); litest_touch_down(dev, 0, 5, 95); - litest_touch_move_to(dev, 0, 5, 95, 5, 99, 5); + litest_touch_move_to(dev, 0, 5, 95, 5, 99, 5, 0); litest_touch_up(dev, 0); } END_TEST @@ -1530,13 +1530,13 @@ START_TEST(touchpad_palm_detect_at_top_corners) litest_drain_events(li); litest_touch_down(dev, 0, 99, 5); - litest_touch_move_to(dev, 0, 99, 5, 99, 9, 10); + litest_touch_move_to(dev, 0, 99, 5, 99, 9, 10, 0); litest_touch_up(dev, 0); litest_assert_empty_queue(li); litest_touch_down(dev, 0, 5, 5); - litest_touch_move_to(dev, 0, 5, 5, 5, 9, 5); + litest_touch_move_to(dev, 0, 5, 5, 5, 9, 5, 0); litest_touch_up(dev, 0); } END_TEST @@ -1552,7 +1552,7 @@ START_TEST(touchpad_palm_detect_palm_stays_palm) litest_drain_events(li); litest_touch_down(dev, 0, 99, 20); - litest_touch_move_to(dev, 0, 99, 20, 75, 99, 5); + litest_touch_move_to(dev, 0, 99, 20, 75, 99, 5, 0); litest_touch_up(dev, 0); litest_assert_empty_queue(li); } @@ -1571,7 +1571,7 @@ START_TEST(touchpad_palm_detect_palm_becomes_pointer) litest_drain_events(li); litest_touch_down(dev, 0, 99, 50); - litest_touch_move_to(dev, 0, 99, 50, 0, 70, 5); + litest_touch_move_to(dev, 0, 99, 50, 0, 70, 5, 0); litest_touch_up(dev, 0); libinput_dispatch(li); @@ -1604,11 +1604,11 @@ START_TEST(touchpad_palm_detect_no_palm_moving_into_edges) litest_drain_events(li); litest_touch_down(dev, 0, 50, 50); - litest_touch_move_to(dev, 0, 50, 50, 99, 50, 5); + litest_touch_move_to(dev, 0, 50, 50, 99, 50, 5, 0); litest_drain_events(li); - litest_touch_move_to(dev, 0, 99, 50, 99, 90, 5); + litest_touch_move_to(dev, 0, 99, 50, 99, 90, 5, 0); libinput_dispatch(li); type = libinput_next_event_type(li); From 83fb3a89bedae6761963e083ed7067b45b3362cb Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 26 Sep 2014 11:46:00 +0200 Subject: [PATCH 2/7] touchpad: Make motion during tap-n-drag test take some time The tap code will move individual touches to a state of TAP_TOUCH_STATE_DEAD after a timeout. In case of tap-n-drag this should not have any influence, make the litest_touch_move_to take long enough to trigger the timeout to verify that this does not has any influence. Signed-off-by: Hans de Goede --- test/touchpad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/touchpad.c b/test/touchpad.c index 576f9ffa..8bd09f19 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -131,7 +131,7 @@ START_TEST(touchpad_1fg_tap_n_drag) litest_touch_down(dev, 0, 50, 50); litest_touch_up(dev, 0); litest_touch_down(dev, 0, 50, 50); - litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 0); + litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40); litest_touch_up(dev, 0); libinput_dispatch(li); @@ -150,7 +150,7 @@ START_TEST(touchpad_1fg_tap_n_drag) /* lift finger, set down again, should continue dragging */ litest_touch_down(dev, 0, 50, 50); - litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 0); + litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40); litest_touch_up(dev, 0); libinput_dispatch(li); From 23031c8fd70a98ef32a80ded6299010ea5e732c2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 25 Sep 2014 15:58:04 +0200 Subject: [PATCH 3/7] touchpad: Don't send scroll events during 2 finger tap-n-drag The touchpad tap code explicitly supports 2 finger tap-n-drag, this commit adds a test-case for this, which fails due to the 2 finger scrolling code sending scroll events during a 2 finger tap-n-drag. And this commit fixes the test-case, by not sending scroll events while a tap-n-drag is active. Signed-off-by: Hans de Goede --- src/evdev-mt-touchpad-tap.c | 13 ++++++++++++ src/evdev-mt-touchpad.c | 4 ++++ src/evdev-mt-touchpad.h | 3 +++ test/touchpad.c | 40 +++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+) diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c index 0b72ace7..8aa4ec6a 100644 --- a/src/evdev-mt-touchpad-tap.c +++ b/src/evdev-mt-touchpad-tap.c @@ -749,3 +749,16 @@ tp_tap_resume(struct tp_dispatch *tp, uint64_t time) { tp_tap_enabled_update(tp, false, tp->tap.enabled, time); } + +bool +tp_tap_dragging(struct tp_dispatch *tp) +{ + switch (tp->tap.state) { + case TAP_STATE_DRAGGING: + case TAP_STATE_DRAGGING_2: + case TAP_STATE_DRAGGING_WAIT: + return true; + default: + return false; + } +} diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index b7a559f9..85d980ce 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -508,6 +508,10 @@ tp_post_scroll_events(struct tp_dispatch *tp, uint64_t time) struct tp_touch *t; int nfingers_down = 0; + /* No scrolling during tap-n-drag */ + if (tp_tap_dragging(tp)) + return 0; + /* Only count active touches for 2 finger scrolling */ tp_for_each_touch(tp, t) { if (tp_touch_active(tp, t)) diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index 2fda4efd..91f6e4ae 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -291,4 +291,7 @@ tp_tap_suspend(struct tp_dispatch *tp, uint64_t time); void tp_tap_resume(struct tp_dispatch *tp, uint64_t time); +bool +tp_tap_dragging(struct tp_dispatch *tp); + #endif diff --git a/test/touchpad.c b/test/touchpad.c index 8bd09f19..fba1d58b 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -200,6 +200,45 @@ START_TEST(touchpad_1fg_tap_n_drag_timeout) } END_TEST +START_TEST(touchpad_2fg_tap_n_drag) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + + libinput_device_config_tap_set_enabled(dev->libinput_device, + LIBINPUT_CONFIG_TAP_ENABLED); + + litest_drain_events(li); + + litest_touch_down(dev, 0, 50, 50); + litest_touch_up(dev, 0); + litest_touch_down(dev, 0, 50, 50); + litest_touch_down(dev, 1, 60, 50); + litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40); + libinput_dispatch(li); + + litest_assert_button_event(li, BTN_LEFT, + LIBINPUT_BUTTON_STATE_PRESSED); + + while (libinput_next_event_type(li) == LIBINPUT_EVENT_POINTER_MOTION) { + event = libinput_get_event(li); + libinput_event_destroy(event); + libinput_dispatch(li); + } + litest_assert_empty_queue(li); + + litest_touch_up(dev, 0); + litest_touch_up(dev, 1); + + /* This will wait for the DRAGGING_WAIT timeout */ + litest_assert_button_event(li, BTN_LEFT, + LIBINPUT_BUTTON_STATE_RELEASED); + + litest_assert_empty_queue(li); +} +END_TEST + START_TEST(touchpad_2fg_tap) { struct litest_device *dev = litest_current_device(); @@ -1934,6 +1973,7 @@ int main(int argc, char **argv) { litest_add("touchpad:tap", touchpad_1fg_tap, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:tap", touchpad_1fg_tap_n_drag, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:tap", touchpad_1fg_tap_n_drag_timeout, LITEST_TOUCHPAD, LITEST_ANY); + litest_add("touchpad:tap", touchpad_2fg_tap_n_drag, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:tap", touchpad_2fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:tap", touchpad_2fg_tap_inverted, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:tap", touchpad_1fg_tap_click, LITEST_TOUCHPAD, LITEST_CLICKPAD); From 6699d1b637e67780fb5034e2648f492a8440b21b Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 25 Sep 2014 16:50:44 +0200 Subject: [PATCH 4/7] touchpad: Add a test for 2fg tap-n-drag release on a 3th finger down Signed-off-by: Hans de Goede --- test/touchpad.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/test/touchpad.c b/test/touchpad.c index fba1d58b..f9031dd9 100644 --- a/test/touchpad.c +++ b/test/touchpad.c @@ -239,6 +239,54 @@ START_TEST(touchpad_2fg_tap_n_drag) } END_TEST +START_TEST(touchpad_2fg_tap_n_drag_3fg_btntool) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct libinput_event *event; + + libinput_device_config_tap_set_enabled(dev->libinput_device, + LIBINPUT_CONFIG_TAP_ENABLED); + + litest_drain_events(li); + + litest_touch_down(dev, 0, 50, 50); + litest_touch_up(dev, 0); + litest_touch_down(dev, 0, 50, 50); + litest_touch_down(dev, 1, 60, 50); + litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40); + libinput_dispatch(li); + + litest_assert_button_event(li, BTN_LEFT, + LIBINPUT_BUTTON_STATE_PRESSED); + + while (libinput_next_event_type(li) == LIBINPUT_EVENT_POINTER_MOTION) { + event = libinput_get_event(li); + libinput_event_destroy(event); + libinput_dispatch(li); + } + litest_assert_empty_queue(li); + + /* Putting down a third finger should end the drag */ + litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1); + litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + libinput_dispatch(li); + + litest_assert_button_event(li, BTN_LEFT, + LIBINPUT_BUTTON_STATE_RELEASED); + + /* Releasing the fingers should not cause any events */ + litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 0); + litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + litest_touch_up(dev, 1); + litest_touch_up(dev, 0); + + litest_assert_empty_queue(li); +} +END_TEST + START_TEST(touchpad_2fg_tap) { struct litest_device *dev = litest_current_device(); @@ -1974,6 +2022,7 @@ int main(int argc, char **argv) { litest_add("touchpad:tap", touchpad_1fg_tap_n_drag, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:tap", touchpad_1fg_tap_n_drag_timeout, LITEST_TOUCHPAD, LITEST_ANY); litest_add("touchpad:tap", touchpad_2fg_tap_n_drag, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add("touchpad:tap", touchpad_2fg_tap_n_drag_3fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_APPLE_CLICKPAD); litest_add("touchpad:tap", touchpad_2fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:tap", touchpad_2fg_tap_inverted, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add("touchpad:tap", touchpad_1fg_tap_click, LITEST_TOUCHPAD, LITEST_CLICKPAD); From 7a64815faa82014f7c45d764170541e0d1773d4d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 6 Nov 2014 11:15:27 +0100 Subject: [PATCH 5/7] touchpad: Make tap code follow state machine diagram part 1 According to the diagram, we should only check the tap-touch-state before sending a button press / release when in state touch_2 or touch_3. tp_tap_notify always checks the tap-touch-state. This is problematic when in state tapped, or one of the follow up states, since this could cause the button 1 release to never happen. In practice this is never a problem since the touch passed into tp_tap_notify is NULL when called for timeout or button events, and in the 2 affected paths where we're dealing with a touch or release tap-touch-state always is TAP_TOUCH_STATE_TOUCH. However we should not rely on this and properly follow the diagram, this commit therefor drops the touch argument to tp_tap_notify, and adds explicit tap-touch-state checks in the places where they are present in the diagram too. Signed-off-by: Hans de Goede --- src/evdev-mt-touchpad-tap.c | 43 ++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c index 8aa4ec6a..edb123ee 100644 --- a/src/evdev-mt-touchpad-tap.c +++ b/src/evdev-mt-touchpad-tap.c @@ -95,16 +95,12 @@ tap_event_to_str(enum tap_event event) { static void tp_tap_notify(struct tp_dispatch *tp, - struct tp_touch *t, uint64_t time, int nfingers, enum libinput_button_state state) { int32_t button; - if (t && t->tap.state == TAP_TOUCH_STATE_DEAD) - return; - switch (nfingers) { case 1: button = BTN_LEFT; break; case 2: button = BTN_RIGHT; break; @@ -174,7 +170,7 @@ tp_tap_touch_handle_event(struct tp_dispatch *tp, break; case TAP_EVENT_RELEASE: tp->tap.state = TAP_STATE_TAPPED; - tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_PRESSED); + tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED); tp_tap_set_timer(tp, time); break; case TAP_EVENT_TIMEOUT: @@ -229,11 +225,11 @@ tp_tap_tapped_handle_event(struct tp_dispatch *tp, break; case TAP_EVENT_TIMEOUT: tp->tap.state = TAP_STATE_IDLE; - tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); + tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); break; case TAP_EVENT_BUTTON: tp->tap.state = TAP_STATE_DEAD; - tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); + tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); break; } } @@ -251,8 +247,10 @@ tp_tap_touch2_handle_event(struct tp_dispatch *tp, break; case TAP_EVENT_RELEASE: tp->tap.state = TAP_STATE_HOLD; - tp_tap_notify(tp, t, time, 2, LIBINPUT_BUTTON_STATE_PRESSED); - tp_tap_notify(tp, t, time, 2, LIBINPUT_BUTTON_STATE_RELEASED); + if (t->tap.state == TAP_TOUCH_STATE_TOUCH) { + tp_tap_notify(tp, time, 2, LIBINPUT_BUTTON_STATE_PRESSED); + tp_tap_notify(tp, time, 2, LIBINPUT_BUTTON_STATE_RELEASED); + } tp_tap_clear_timer(tp); break; case TAP_EVENT_MOTION: @@ -309,8 +307,10 @@ tp_tap_touch3_handle_event(struct tp_dispatch *tp, break; case TAP_EVENT_RELEASE: tp->tap.state = TAP_STATE_TOUCH_2_HOLD; - tp_tap_notify(tp, t, time, 3, LIBINPUT_BUTTON_STATE_PRESSED); - tp_tap_notify(tp, t, time, 3, LIBINPUT_BUTTON_STATE_RELEASED); + if (t->tap.state == TAP_TOUCH_STATE_TOUCH) { + tp_tap_notify(tp, time, 3, LIBINPUT_BUTTON_STATE_PRESSED); + tp_tap_notify(tp, time, 3, LIBINPUT_BUTTON_STATE_RELEASED); + } break; case TAP_EVENT_BUTTON: tp->tap.state = TAP_STATE_DEAD; @@ -352,9 +352,9 @@ tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp, break; case TAP_EVENT_RELEASE: tp->tap.state = TAP_STATE_IDLE; - tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); - tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_PRESSED); - tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); + tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); + tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED); + tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); tp_tap_clear_timer(tp); break; case TAP_EVENT_MOTION: @@ -363,7 +363,7 @@ 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, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); + tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); break; } } @@ -388,7 +388,7 @@ tp_tap_dragging_handle_event(struct tp_dispatch *tp, break; case TAP_EVENT_BUTTON: tp->tap.state = TAP_STATE_DEAD; - tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); + tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); break; } } @@ -409,11 +409,11 @@ tp_tap_dragging_wait_handle_event(struct tp_dispatch *tp, break; case TAP_EVENT_TIMEOUT: tp->tap.state = TAP_STATE_IDLE; - tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); + tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); break; case TAP_EVENT_BUTTON: tp->tap.state = TAP_STATE_DEAD; - tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); + tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); break; } } @@ -430,7 +430,7 @@ tp_tap_dragging2_handle_event(struct tp_dispatch *tp, break; case TAP_EVENT_TOUCH: tp->tap.state = TAP_STATE_DEAD; - tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); + tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); break; case TAP_EVENT_MOTION: case TAP_EVENT_TIMEOUT: @@ -438,7 +438,7 @@ tp_tap_dragging2_handle_event(struct tp_dispatch *tp, break; case TAP_EVENT_BUTTON: tp->tap.state = TAP_STATE_DEAD; - tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); + tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED); break; } } @@ -731,8 +731,7 @@ tp_release_all_taps(struct tp_dispatch *tp, uint64_t now) for (i = 1; i <= 3; i++) { if (tp->tap.buttons_pressed & (1 << i)) - tp_tap_notify(tp, NULL, now, i, - LIBINPUT_BUTTON_STATE_RELEASED); + tp_tap_notify(tp, now, i, LIBINPUT_BUTTON_STATE_RELEASED); } tp->tap.state = tp->nfingers_down ? TAP_STATE_DEAD : TAP_STATE_IDLE; From d2c44df7c337d506cc914eaf16931828547f2fd0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 28 Sep 2014 12:49:06 +0200 Subject: [PATCH 6/7] touchpad: Make tap code follow state machine diagram part 2 Mark touches as idle, rather then dead, on release. This causes no functional changes since we only evert check for tap-touch-state == touch, and neither being idle or dead == touch. Signed-off-by: Hans de Goede --- src/evdev-mt-touchpad-tap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c index edb123ee..d15e9ea9 100644 --- a/src/evdev-mt-touchpad-tap.c +++ b/src/evdev-mt-touchpad-tap.c @@ -570,7 +570,7 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time) tp_tap_handle_event(tp, t, TAP_EVENT_TOUCH, time); } else if (t->state == TOUCH_END) { tp_tap_handle_event(tp, t, TAP_EVENT_RELEASE, time); - t->tap.state = TAP_TOUCH_STATE_DEAD; + t->tap.state = TAP_TOUCH_STATE_IDLE; } else if (tp->tap.state != TAP_STATE_IDLE && tp_tap_exceeds_motion_threshold(tp, t)) { struct tp_touch *tmp; From a78a25e62eaec24d625a48d9d0dcd524f874ad7f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 28 Sep 2014 12:51:09 +0200 Subject: [PATCH 7/7] touchpad: Make tap code follow state machine diagram part 3 We should only mark touches dead on a button click if we're dealing with a clickpad. Signed-off-by: Hans de Goede --- src/evdev-mt-touchpad-tap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c index d15e9ea9..a38edbe3 100644 --- a/src/evdev-mt-touchpad-tap.c +++ b/src/evdev-mt-touchpad-tap.c @@ -562,7 +562,8 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time) if (!t->dirty || t->state == TOUCH_NONE) continue; - if (tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS) + if (tp->buttons.is_clickpad && + tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS) t->tap.state = TAP_TOUCH_STATE_DEAD; if (t->state == TOUCH_BEGIN) {