evdev: add "READY" state to button scrolling
authorPeter Hutterer <peter.hutterer@who-t.net>
Mon, 20 Feb 2017 03:32:07 +0000 (13:32 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Mon, 20 Feb 2017 11:16:34 +0000 (21:16 +1000)
Before, our states were idle, button down and scrolling. This adds a state
where the button is down and the timeout has expired (i.e. we're ready to send
scroll events) but we haven't actually sent any events anymore.

If the button is released in this state, we generate a normal click event.

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

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

index a50d7fa..d50f9bb 100644 (file)
@@ -221,7 +221,7 @@ evdev_button_scroll_timeout(uint64_t time, void *data)
 {
        struct evdev_device *device = data;
 
-       device->scroll.button_scroll_state = BUTTONSCROLL_SCROLLING;
+       device->scroll.button_scroll_state = BUTTONSCROLL_READY;
 }
 
 static void
@@ -260,9 +260,12 @@ evdev_button_scroll_button(struct evdev_device *device,
                                         "invalid state IDLE for button up\n");
                        break;
                case BUTTONSCROLL_BUTTON_DOWN:
+               case BUTTONSCROLL_READY:
                        log_debug(evdev_libinput_context(device),
                                  "btnscroll: cancel\n");
-                       /* If the button is released quickly enough emit the
+
+                       /* If the button is released quickly enough or
+                        * without scroll events, emit the
                         * button press/release events. */
                        evdev_pointer_post_button(device,
                                        device->scroll.button_down_time,
@@ -401,6 +404,9 @@ evdev_post_trackpoint_scroll(struct evdev_device *device,
                log_debug(evdev_libinput_context(device),
                          "btnscroll: discarding\n");
                return true;
+       case BUTTONSCROLL_READY:
+               device->scroll.button_scroll_state = BUTTONSCROLL_SCROLLING;
+               /* fallthrough */
        case BUTTONSCROLL_SCROLLING:
                evdev_post_scroll(device, time,
                                  LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
index d481d5c..392d71c 100644 (file)
@@ -132,7 +132,8 @@ enum evdev_device_model {
 enum evdev_button_scroll_state {
        BUTTONSCROLL_IDLE,
        BUTTONSCROLL_BUTTON_DOWN,       /* button is down */
-       BUTTONSCROLL_SCROLLING,         /* scrolling */
+       BUTTONSCROLL_READY,             /* ready for scroll events */
+       BUTTONSCROLL_SCROLLING,         /* have sent scroll events */
 };
 
 struct mt_slot {
index f6dae75..8498da9 100644 (file)
@@ -1006,11 +1006,15 @@ START_TEST(pointer_scroll_button)
        litest_button_scroll(dev, BTN_LEFT, -9, 1);
        litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -9);
 
-       /* scroll smaller than the threshold should not generate events */
+       /* scroll smaller than the threshold should not generate axis events */
        litest_button_scroll(dev, BTN_LEFT, 1, 1);
-       /* left press without movement should not generate events */
-       litest_button_scroll(dev, BTN_LEFT, 0, 0);
 
+       litest_button_scroll(dev, BTN_LEFT, 0, 0);
+       litest_assert_button_event(li, BTN_LEFT,
+                                  LIBINPUT_BUTTON_STATE_PRESSED);
+       litest_assert_button_event(li,
+                                  BTN_LEFT,
+                                  LIBINPUT_BUTTON_STATE_RELEASED);
        litest_assert_empty_queue(li);
 
        /* Restore default scroll behavior */
@@ -1076,6 +1080,12 @@ START_TEST(pointer_scroll_button_no_event_before_timeout)
        litest_timeout_buttonscroll();
        libinput_dispatch(li);
        litest_button_click(device, BTN_LEFT, false);
+
+       litest_assert_button_event(li, BTN_LEFT,
+                                  LIBINPUT_BUTTON_STATE_PRESSED);
+       litest_assert_button_event(li,
+                                  BTN_LEFT,
+                                  LIBINPUT_BUTTON_STATE_RELEASED);
        litest_assert_empty_queue(li);
 }
 END_TEST
index e9ba027..adbd46e 100644 (file)
@@ -85,10 +85,15 @@ START_TEST(trackpoint_scroll)
        litest_button_scroll(dev, BTN_MIDDLE, -9, 1);
        litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -9);
 
-       /* scroll smaller than the threshold should not generate events */
+       /* scroll smaller than the threshold should not generate axis events */
        litest_button_scroll(dev, BTN_MIDDLE, 1, 1);
-       /* long middle press without movement should not generate events */
+
        litest_button_scroll(dev, BTN_MIDDLE, 0, 0);
+       litest_assert_button_event(li, BTN_MIDDLE,
+                                  LIBINPUT_BUTTON_STATE_PRESSED);
+       litest_assert_button_event(li,
+                                  BTN_MIDDLE,
+                                  LIBINPUT_BUTTON_STATE_RELEASED);
 
        litest_assert_empty_queue(li);
 }