touchpad: ignore hovering touches for the software button state
authorPeter Hutterer <peter.hutterer@who-t.net>
Wed, 1 Mar 2017 01:26:06 +0000 (11:26 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Wed, 1 Mar 2017 22:34:17 +0000 (08:34 +1000)
If a touch started hovering in the main area, the button state would start
with AREA and never move to the real button state, despite the finger
triggering the pressure thresholds correctly in one of the areas.

This could even happen across touch sequences if a touch went below pressure
in the software button area, it changed to hovering and the button state
changed to NONE. On the next event, the touch is still hovering and the
current position of the touch is taken for the button state machine.

https://bugs.freedesktop.org/show_bug.cgi?id=99976

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
src/evdev-mt-touchpad-buttons.c
test/test-touchpad-buttons.c

index 176b431e77354a1d90fba5670cb1e1302a98edf0..895cf0ea126e70e012fe57f7ce1cc32e12ed32ef 100644 (file)
@@ -457,7 +457,7 @@ tp_button_handle_state(struct tp_dispatch *tp, uint64_t time)
        struct tp_touch *t;
 
        tp_for_each_touch(tp, t) {
-               if (t->state == TOUCH_NONE)
+               if (t->state == TOUCH_NONE || t->state == TOUCH_HOVERING)
                        continue;
 
                if (t->state == TOUCH_END) {
index 820d8f09d692956031225cd3e784b4f9a2af7ebe..0037ba773fbf3f699e6ed5a1934fbf17eff57b27 100644 (file)
@@ -1476,6 +1476,37 @@ START_TEST(clickpad_softbutton_right_to_left)
 }
 END_TEST
 
+START_TEST(clickpad_softbutton_hover_into_buttons)
+{
+       struct litest_device *dev = litest_current_device();
+       struct libinput *li = dev->libinput;
+
+       litest_drain_events(li);
+
+       litest_hover_start(dev, 0, 50, 50);
+       libinput_dispatch(li);
+       litest_hover_move_to(dev, 0, 50, 50, 90, 90, 10, 0);
+       libinput_dispatch(li);
+
+       litest_touch_move_to(dev, 0, 90, 90, 91, 91, 1, 0);
+
+       litest_button_click(dev, BTN_LEFT, true);
+       libinput_dispatch(li);
+
+       litest_assert_button_event(li,
+                                  BTN_RIGHT,
+                                  LIBINPUT_BUTTON_STATE_PRESSED);
+       litest_assert_empty_queue(li);
+
+       litest_button_click(dev, BTN_LEFT, false);
+       litest_touch_up(dev, 0);
+
+       litest_assert_button_event(li,
+                                  BTN_RIGHT,
+                                  LIBINPUT_BUTTON_STATE_RELEASED);
+}
+END_TEST
+
 START_TEST(clickpad_topsoftbuttons_left)
 {
        struct litest_device *dev = litest_current_device();
@@ -1962,6 +1993,7 @@ litest_setup_tests_touchpad_buttons(void)
        litest_add("touchpad:softbutton", clickpad_softbutton_left_2nd_fg_move, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
        litest_add("touchpad:softbutton", clickpad_softbutton_left_to_right, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
        litest_add("touchpad:softbutton", clickpad_softbutton_right_to_left, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
+       litest_add("touchpad:softbutton", clickpad_softbutton_hover_into_buttons, LITEST_CLICKPAD|LITEST_HOVER, LITEST_APPLE_CLICKPAD);
 
        litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_left, LITEST_TOPBUTTONPAD, LITEST_ANY);
        litest_add("touchpad:topsoftbuttons", clickpad_topsoftbuttons_right, LITEST_TOPBUTTONPAD, LITEST_ANY);