diff --git a/0001-touchpad-don-t-tap-for-2fg-down-followed-by-a-single.patch b/0001-touchpad-don-t-tap-for-2fg-down-followed-by-a-single.patch new file mode 100644 index 0000000..f515bde --- /dev/null +++ b/0001-touchpad-don-t-tap-for-2fg-down-followed-by-a-single.patch @@ -0,0 +1,594 @@ +From 79570fd492691b4ce97360e7775965e5765a702b Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Mon, 31 Aug 2015 11:10:58 +1000 +Subject: [PATCH libinput] touchpad: don't tap for 2fg down, followed by a + single finger up + +The following sequence currently generates a right-button event: + finger 1 down + finger 2 down + finger 1 up + finger 2 held down + +This is easily triggered with short scroll events. There are two issues here: +first is that the tapping code elsewhere treats any tap with a second finger +down as a left-button tap, not a right button one. So if anything, we should +generate a left button click here, not a right button click. + +Arguably, generating a button click here is wrong though, it's not a very well +defined sequence and relatively difficult to trigger intentionally. So the +best solution here is to simply ignore the release event and move straight +back to state HOLD - unless the second finger is released within the timeout. +If the finger is set down again during the timeout, we move straight to +TOUCH_2_HOLD - this could eventually be interpreted as a tap, but not for now. + +Signed-off-by: Peter Hutterer +Reviewed-by: Hans de Goede +--- + doc/touchpad-tap-state-machine.svg | 254 +++++++++++++++++++++++-------------- + src/evdev-mt-touchpad-tap.c | 41 +++++- + src/evdev-mt-touchpad.h | 1 + + test/touchpad-tap.c | 46 +++++++ + 4 files changed, 240 insertions(+), 102 deletions(-) + +diff --git a/doc/touchpad-tap-state-machine.svg b/doc/touchpad-tap-state-machine.svg +index b1c5995..9fee48a 100644 +--- a/doc/touchpad-tap-state-machine.svg ++++ b/doc/touchpad-tap-state-machine.svg +@@ -35,11 +35,11 @@ + + + +- ++ + +- ++ + button 1 +- ++ + press + + +@@ -72,20 +72,20 @@ + + TOUCH_2 + +- ++ + +- ++ + second +- ++ + finger up + +- +- +- ++ ++ ++ + +- ++ + button 2 +- ++ + press + + +@@ -104,45 +104,45 @@ + + + +- ++ + +- ++ + button 1 +- ++ + release + +- ++ + +- ++ + button 2 +- ++ + release + +- +- +- +- +- ++ ++ ++ ++ ++ + +- ++ + TAPPED + +- ++ + +- ++ + timeout + +- +- +- ++ ++ ++ + +- ++ + first +- ++ + finger down + +- +- ++ ++ + + + +@@ -164,10 +164,10 @@ + + + +- +- +- +- ++ ++ ++ ++ + + + +@@ -226,18 +226,18 @@ + + + +- ++ + +- ++ + first +- ++ + finger up + +- +- +- ++ ++ ++ + +- ++ + IDLE + + +@@ -249,8 +249,8 @@ + + + +- +- ++ ++ + + + +@@ -344,8 +344,6 @@ + + + +- +- + + + +@@ -371,7 +369,7 @@ + + + +- ++ + + + +@@ -558,8 +556,8 @@ + + press + +- +- ++ ++ + + + +@@ -607,15 +605,15 @@ + + TOUCH_TOUCH + +- ++ + +- ++ + TOUCH_IDLE + +- +- +- +- ++ ++ ++ ++ + + + +@@ -631,15 +629,8 @@ + + + +- +- +- +- +- +- +- +- yes +- ++ ++ + + + +@@ -667,27 +658,20 @@ + + + +- ++ + +- ++ + TOUCH_IDLE + +- +- +- ++ ++ ++ + +- ++ + TOUCH_IDLE + +- +- +- +- +- +- TOUCH_IDLE +- +- +- ++ ++ + + + +@@ -736,8 +720,8 @@ + + TOUCH_TOUCH + +- +- ++ ++ + + + +@@ -860,13 +844,6 @@ + + + +- +- +- +- state == +- +- TOUCH_TOUCH +- + + + +@@ -874,13 +851,6 @@ + + TOUCH_TOUCH + +- +- +- +- +- +- no +- + + + +@@ -1197,5 +1167,97 @@ + + + ++ ++ ++ ++ TOUCH_2_RELEASE ++ ++ ++ ++ ++ second ++ ++ finger up ++ ++ ++ ++ ++ ++ ++ timeout ++ ++ ++ ++ ++ ++ ++ move > ++ ++ threshold ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ first ++ ++ finger down ++ ++ ++ ++ ++ ++ ++ ++ ++ TOUCH_IDLE ++ ++ ++ ++ ++ ++ ++ first ++ ++ finger up ++ ++ ++ ++ ++ ++ ++ ++ ++ second ++ ++ finger down ++ ++ ++ ++ ++ ++ ++ TOUCH_DEAD ++ ++ ++ ++ ++ TOUCH_DEAD ++ ++ ++ ++ ++ ++ ++ ++ ++ + + +diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c +index de4945e..753fc6b 100644 +--- a/src/evdev-mt-touchpad-tap.c ++++ b/src/evdev-mt-touchpad-tap.c +@@ -69,6 +69,7 @@ tap_state_to_str(enum tp_tap_state state) + CASE_RETURN_STRING(TAP_STATE_TAPPED); + CASE_RETURN_STRING(TAP_STATE_TOUCH_2); + CASE_RETURN_STRING(TAP_STATE_TOUCH_2_HOLD); ++ CASE_RETURN_STRING(TAP_STATE_TOUCH_2_RELEASE); + CASE_RETURN_STRING(TAP_STATE_TOUCH_3); + CASE_RETURN_STRING(TAP_STATE_TOUCH_3_HOLD); + CASE_RETURN_STRING(TAP_STATE_DRAGGING); +@@ -275,12 +276,8 @@ tp_tap_touch2_handle_event(struct tp_dispatch *tp, + tp_tap_set_timer(tp, time); + break; + case TAP_EVENT_RELEASE: +- tp->tap.state = TAP_STATE_HOLD; +- 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); ++ tp->tap.state = TAP_STATE_TOUCH_2_RELEASE; ++ tp_tap_set_timer(tp, time); + break; + case TAP_EVENT_MOTION: + tp_tap_clear_timer(tp); +@@ -323,6 +320,35 @@ tp_tap_touch2_hold_handle_event(struct tp_dispatch *tp, + } + + static void ++tp_tap_touch2_release_handle_event(struct tp_dispatch *tp, ++ struct tp_touch *t, ++ enum tap_event event, uint64_t time) ++{ ++ ++ switch (event) { ++ case TAP_EVENT_TOUCH: ++ tp->tap.state = TAP_STATE_TOUCH_2_HOLD; ++ t->tap.state = TAP_TOUCH_STATE_DEAD; ++ tp_tap_clear_timer(tp); ++ break; ++ case TAP_EVENT_RELEASE: ++ tp_tap_notify(tp, time, 2, LIBINPUT_BUTTON_STATE_PRESSED); ++ tp_tap_notify(tp, time, 2, LIBINPUT_BUTTON_STATE_RELEASED); ++ tp->tap.state = TAP_STATE_IDLE; ++ break; ++ case TAP_EVENT_MOTION: ++ case TAP_EVENT_TIMEOUT: ++ tp->tap.state = TAP_STATE_HOLD; ++ break; ++ case TAP_EVENT_BUTTON: ++ tp->tap.state = TAP_STATE_DEAD; ++ break; ++ case TAP_EVENT_THUMB: ++ break; ++ } ++} ++ ++static void + tp_tap_touch3_handle_event(struct tp_dispatch *tp, + struct tp_touch *t, + enum tap_event event, uint64_t time) +@@ -649,6 +675,9 @@ tp_tap_handle_event(struct tp_dispatch *tp, + case TAP_STATE_TOUCH_2_HOLD: + tp_tap_touch2_hold_handle_event(tp, t, event, time); + break; ++ case TAP_STATE_TOUCH_2_RELEASE: ++ tp_tap_touch2_release_handle_event(tp, t, event, time); ++ break; + case TAP_STATE_TOUCH_3: + tp_tap_touch3_handle_event(tp, t, event, time); + break; +diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h +index 5f87c3f..f42fb02 100644 +--- a/src/evdev-mt-touchpad.h ++++ b/src/evdev-mt-touchpad.h +@@ -97,6 +97,7 @@ enum tp_tap_state { + TAP_STATE_TAPPED, + TAP_STATE_TOUCH_2, + TAP_STATE_TOUCH_2_HOLD, ++ TAP_STATE_TOUCH_2_RELEASE, + TAP_STATE_TOUCH_3, + TAP_STATE_TOUCH_3_HOLD, + TAP_STATE_DRAGGING_OR_DOUBLETAP, +diff --git a/test/touchpad-tap.c b/test/touchpad-tap.c +index 62c7a5c..334d797 100644 +--- a/test/touchpad-tap.c ++++ b/test/touchpad-tap.c +@@ -966,6 +966,50 @@ START_TEST(touchpad_2fg_tap_inverted) + } + END_TEST + ++START_TEST(touchpad_2fg_tap_n_hold_first) ++{ ++ struct litest_device *dev = litest_current_device(); ++ struct libinput *li = dev->libinput; ++ ++ litest_enable_tap(dev->libinput_device); ++ ++ litest_drain_events(dev->libinput); ++ ++ litest_touch_down(dev, 0, 50, 50); ++ litest_touch_down(dev, 1, 70, 70); ++ litest_touch_up(dev, 1); ++ ++ libinput_dispatch(li); ++ ++ litest_assert_empty_queue(li); ++ litest_timeout_tap(); ++ ++ litest_assert_empty_queue(li); ++} ++END_TEST ++ ++START_TEST(touchpad_2fg_tap_n_hold_second) ++{ ++ struct litest_device *dev = litest_current_device(); ++ struct libinput *li = dev->libinput; ++ ++ litest_enable_tap(dev->libinput_device); ++ ++ litest_drain_events(dev->libinput); ++ ++ litest_touch_down(dev, 0, 50, 50); ++ litest_touch_down(dev, 1, 70, 70); ++ litest_touch_up(dev, 0); ++ ++ libinput_dispatch(li); ++ ++ litest_assert_empty_queue(li); ++ litest_timeout_tap(); ++ ++ litest_assert_empty_queue(li); ++} ++END_TEST ++ + START_TEST(touchpad_2fg_tap_quickrelease) + { + struct litest_device *dev = litest_current_device(); +@@ -1755,6 +1799,8 @@ litest_setup_tests(void) + litest_add("touchpad:tap", touchpad_2fg_tap_n_drag_3fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add("touchpad:tap", touchpad_2fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT); + litest_add("touchpad:tap", touchpad_2fg_tap_inverted, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); ++ litest_add("touchpad:tap", touchpad_2fg_tap_n_hold_first, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); ++ litest_add("touchpad:tap", touchpad_2fg_tap_n_hold_second, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add("touchpad:tap", touchpad_2fg_tap_quickrelease, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_SEMI_MT); + litest_add("touchpad:tap", touchpad_1fg_tap_click, LITEST_TOUCHPAD|LITEST_BUTTON, LITEST_CLICKPAD); + litest_add("touchpad:tap", touchpad_2fg_tap_click, LITEST_TOUCHPAD|LITEST_BUTTON, LITEST_SINGLE_TOUCH|LITEST_CLICKPAD); +-- +2.4.3 + diff --git a/libinput.spec b/libinput.spec index 844d3e7..e0d5ed6 100644 --- a/libinput.spec +++ b/libinput.spec @@ -5,7 +5,7 @@ Name: libinput Version: 1.0.1 -Release: 1%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist} +Release: 2%{?gitdate:.%{gitdate}git%{gitversion}}%{?dist} Summary: Input device library License: MIT @@ -21,6 +21,9 @@ Source0: http://www.freedesktop.org/software/libinput/libinput-%{version} # Not upstream, keep until kernel 4.2 or 4.1.x with dbf3c37086 Patch01: 0001-touchpad-serial-synaptics-need-to-fake-new-touches-o.patch +# Bug 1256045 - Libinput regularly interprets two-finger scrolling as right-mouse click +Patch02: 0001-touchpad-don-t-tap-for-2fg-down-followed-by-a-single.patch + BuildRequires: git BuildRequires: autoconf automake libtool pkgconfig BuildRequires: libevdev-devel @@ -97,6 +100,9 @@ find $RPM_BUILD_ROOT -name '*.la' -delete %changelog +* Mon Sep 07 2015 Peter Hutterer 1.0.1-2 +- Don't interpret short scrolls as right click (#1256045) + * Thu Sep 03 2015 Peter Hutterer 1.0.1-1 - libinput 1.0.1