From 23031c8fd70a98ef32a80ded6299010ea5e732c2 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 25 Sep 2014 15:58:04 +0200 Subject: 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 +++ 3 files changed, 20 insertions(+) (limited to 'src') 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 -- cgit v1.2.1 From 7a64815faa82014f7c45d764170541e0d1773d4d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 6 Nov 2014 11:15:27 +0100 Subject: 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(-) (limited to 'src') 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; -- cgit v1.2.1 From d2c44df7c337d506cc914eaf16931828547f2fd0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 28 Sep 2014 12:49:06 +0200 Subject: 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(-) (limited to 'src') 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; -- cgit v1.2.1 From a78a25e62eaec24d625a48d9d0dcd524f874ad7f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 28 Sep 2014 12:51:09 +0200 Subject: 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(-) (limited to 'src') 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) { -- cgit v1.2.1