[PATCH libinput] touchpad: send a left button event when we move out of topbuttons and click

Peter Hutterer peter.hutterer at who-t.net
Tue Jun 27 02:27:08 UTC 2017


We used to completely ignore a finger that was within the top software button
area and then moved to the main area and remained there for a timeout. This
avoids erroneous pointer movements when the user moves the finger while using
the trackpoint.

But we also ignored physical clicks, something we should not be doing. This
patch fixes that behavior: we still ignore the finger for movement, but a
physical click now triggers a left click once we've been in the area for the
timeout.

This new behavior doesn't apply within the timeout, i.e. if a finger is in the
right top button area, moves out and immediately clicks, we still trigger a
right click. This avoids erroneous switches to left-clicks when the finger is
at the edge of the button area and moves out during the press.

Related to: https://bugs.freedesktop.org/show_bug.cgi?id=99212

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
Note, this doesn't yet include the state diagram svg change, I'll do that
before pushing.

 src/evdev-mt-touchpad-buttons.c |  3 +++
 test/test-touchpad-buttons.c    | 50 +++++++++++++++++++++++++++++++++++------
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index c437ddf2..83a38c2b 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -405,7 +405,10 @@ tp_button_ignore_handle_event(struct tp_dispatch *tp,
 		tp_button_set_state(tp, t, BUTTON_STATE_NONE, event);
 		break;
 	case BUTTON_EVENT_PRESS:
+		t->button.curr = BUTTON_EVENT_IN_AREA;
+		break;
 	case BUTTON_EVENT_RELEASE:
+		break;
 	case BUTTON_EVENT_TIMEOUT:
 		break;
 	}
diff --git a/test/test-touchpad-buttons.c b/test/test-touchpad-buttons.c
index 0037ba77..9f38e833 100644
--- a/test/test-touchpad-buttons.c
+++ b/test/test-touchpad-buttons.c
@@ -1591,26 +1591,60 @@ START_TEST(clickpad_topsoftbuttons_middle)
 }
 END_TEST
 
-START_TEST(clickpad_topsoftbuttons_move_out_ignore)
+START_TEST(clickpad_topsoftbuttons_move_out_leftclick_before_timeout)
 {
 	struct litest_device *dev = litest_current_device();
 	struct libinput *li = dev->libinput;
 
-	/* Finger down in top button area, wait past enter timeout
+	/* Finger down in top right button area, wait past enter timeout
 	   Move into main area, wait past leave timeout
 	   Click
-	     -> expect no events
+	     -> expect left click
 	 */
 
 	litest_drain_events(li);
 
-	litest_touch_down(dev, 0, 50, 5);
+	litest_touch_down(dev, 0, 80, 5);
 	libinput_dispatch(li);
 	litest_timeout_softbuttons();
 	libinput_dispatch(li);
 	litest_assert_empty_queue(li);
 
-	litest_touch_move_to(dev, 0, 50, 5, 80, 90, 20, 0);
+	litest_touch_move_to(dev, 0, 80, 5, 80, 90, 20, 0);
+	libinput_dispatch(li);
+
+	litest_event(dev, EV_KEY, BTN_LEFT, 1);
+	litest_event(dev, EV_SYN, SYN_REPORT, 0);
+	litest_event(dev, EV_KEY, BTN_LEFT, 0);
+	litest_event(dev, EV_SYN, SYN_REPORT, 0);
+
+	litest_touch_up(dev, 0);
+
+	litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
+	litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
+}
+END_TEST
+
+START_TEST(clickpad_topsoftbuttons_move_out_leftclick)
+{
+	struct litest_device *dev = litest_current_device();
+	struct libinput *li = dev->libinput;
+
+	/* Finger down in top right button area, wait past enter timeout
+	   Move into main area, wait past leave timeout
+	   Click
+	     -> expect left click
+	 */
+
+	litest_drain_events(li);
+
+	litest_touch_down(dev, 0, 80, 5);
+	libinput_dispatch(li);
+	litest_timeout_softbuttons();
+	libinput_dispatch(li);
+	litest_assert_empty_queue(li);
+
+	litest_touch_move_to(dev, 0, 80, 5, 80, 90, 20, 0);
 	libinput_dispatch(li);
 	litest_timeout_softbuttons();
 	libinput_dispatch(li);
@@ -1622,7 +1656,8 @@ START_TEST(clickpad_topsoftbuttons_move_out_ignore)
 
 	litest_touch_up(dev, 0);
 
-	litest_assert_empty_queue(li);
+	litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
+	litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
 }
 END_TEST
 
@@ -1998,7 +2033,8 @@ litest_setup_tests_touchpad_buttons(void)
 	litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_left, LITEST_TOPBUTTONPAD, LITEST_ANY);
 	litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_right, LITEST_TOPBUTTONPAD, LITEST_ANY);
 	litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_middle, LITEST_TOPBUTTONPAD, LITEST_ANY);
-	litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_move_out_ignore, LITEST_TOPBUTTONPAD, LITEST_ANY);
+	litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_move_out_leftclick, LITEST_TOPBUTTONPAD, LITEST_ANY);
+	litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_move_out_leftclick_before_timeout, LITEST_TOPBUTTONPAD, LITEST_ANY);
 	litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_clickfinger, LITEST_TOPBUTTONPAD, LITEST_ANY);
 	litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_clickfinger_dev_disabled, LITEST_TOPBUTTONPAD, LITEST_ANY);
 
-- 
2.13.0



More information about the wayland-devel mailing list