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

Signed-off-by: Peter Hutterer <[email protected]>
---
 src/evdev.c    | 107 ++++++++++++++++++++++++++++++++-------------------------
 src/evdev.h    |   2 +-
 test/pointer.c |  53 ++++++++++++++++++++++++++++
 3 files changed, 114 insertions(+), 48 deletions(-)

diff --git a/src/evdev.c b/src/evdev.c
index e272f4b..9c73e5e 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -154,14 +154,17 @@ evdev_pointer_notify_physical_button(struct evdev_device 
*device,
                                             state))
                        return;
 
-       evdev_pointer_notify_button(device, time, button, state);
+       evdev_pointer_notify_button(device,
+                                   time,
+                                   (unsigned int)button,
+                                   state);
 }
 
-void
-evdev_pointer_notify_button(struct evdev_device *device,
-                           uint64_t time,
-                           int button,
-                           enum libinput_button_state state)
+static void
+evdev_pointer_post_button(struct evdev_device *device,
+                         uint64_t time,
+                         unsigned int button,
+                         enum libinput_button_state state)
 {
        int down_count;
 
@@ -182,6 +185,57 @@ evdev_pointer_notify_button(struct evdev_device *device,
 
 }
 
+static void
+evdev_button_scroll_timeout(uint64_t time, void *data)
+{
+       struct evdev_device *device = data;
+
+       device->scroll.button_scroll_active = true;
+}
+
+static void
+evdev_button_scroll_button(struct evdev_device *device,
+                          uint64_t time, int is_press)
+{
+       if (is_press) {
+               libinput_timer_set(&device->scroll.timer,
+                                  time + DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT);
+               device->scroll.button_down_time = time;
+       } else {
+               libinput_timer_cancel(&device->scroll.timer);
+               if (device->scroll.button_scroll_active) {
+                       evdev_stop_scroll(device, time,
+                                         
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
+                       device->scroll.button_scroll_active = false;
+               } else {
+                       /* If the button is released quickly enough emit the
+                        * button press/release events. */
+                       evdev_pointer_post_button(device,
+                                       device->scroll.button_down_time,
+                                       device->scroll.button,
+                                       LIBINPUT_BUTTON_STATE_PRESSED);
+                       evdev_pointer_post_button(device, time,
+                                       device->scroll.button,
+                                       LIBINPUT_BUTTON_STATE_RELEASED);
+               }
+       }
+}
+
+void
+evdev_pointer_notify_button(struct evdev_device *device,
+                           uint64_t time,
+                           unsigned int button,
+                           enum libinput_button_state state)
+{
+       if (device->scroll.method == LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN &&
+           button == device->scroll.button) {
+               evdev_button_scroll_button(device, time, state);
+               return;
+       }
+
+       evdev_pointer_post_button(device, time, button, state);
+}
+
 void
 evdev_device_led_update(struct evdev_device *device, enum libinput_led leds)
 {
@@ -480,42 +534,6 @@ get_key_type(uint16_t code)
 }
 
 static void
-evdev_button_scroll_timeout(uint64_t time, void *data)
-{
-       struct evdev_device *device = data;
-
-       device->scroll.button_scroll_active = true;
-}
-
-static void
-evdev_button_scroll_button(struct evdev_device *device,
-                          uint64_t time, int is_press)
-{
-       if (is_press) {
-               libinput_timer_set(&device->scroll.timer,
-                                  time + DEFAULT_MIDDLE_BUTTON_SCROLL_TIMEOUT);
-               device->scroll.button_down_time = time;
-       } else {
-               libinput_timer_cancel(&device->scroll.timer);
-               if (device->scroll.button_scroll_active) {
-                       evdev_stop_scroll(device, time,
-                                         
LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS);
-                       device->scroll.button_scroll_active = false;
-               } else {
-                       /* If the button is released quickly enough emit the
-                        * button press/release events. */
-                       evdev_pointer_notify_button(device,
-                                       device->scroll.button_down_time,
-                                       device->scroll.button,
-                                       LIBINPUT_BUTTON_STATE_PRESSED);
-                       evdev_pointer_notify_button(device, time,
-                                       device->scroll.button,
-                                       LIBINPUT_BUTTON_STATE_RELEASED);
-               }
-       }
-}
-
-static void
 evdev_process_touch_button(struct evdev_device *device,
                           uint64_t time, int value)
 {
@@ -575,11 +593,6 @@ evdev_process_key(struct evdev_device *device,
                                   LIBINPUT_KEY_STATE_RELEASED);
                break;
        case EVDEV_KEY_TYPE_BUTTON:
-               if (device->scroll.method == 
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN &&
-                   e->code == device->scroll.button) {
-                       evdev_button_scroll_button(device, time, e->value);
-                       break;
-               }
                evdev_pointer_notify_physical_button(
                        device,
                        time,
diff --git a/src/evdev.h b/src/evdev.h
index 4a5d807..9636af7 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -397,7 +397,7 @@ evdev_keyboard_notify_key(struct evdev_device *device,
 void
 evdev_pointer_notify_button(struct evdev_device *device,
                            uint64_t time,
-                           int button,
+                           unsigned int button,
                            enum libinput_button_state state);
 void
 evdev_pointer_notify_physical_button(struct evdev_device *device,
diff --git a/test/pointer.c b/test/pointer.c
index a34740a..d1d2fda 100644
--- a/test/pointer.c
+++ b/test/pointer.c
@@ -893,6 +893,58 @@ START_TEST(pointer_scroll_button)
 }
 END_TEST
 
+START_TEST(pointer_scroll_button_middle_emulation)
+{
+       struct litest_device *dev = litest_current_device();
+       struct libinput_device *device = dev->libinput_device;
+       struct libinput *li = dev->libinput;
+       enum libinput_config_status status;
+       int i;
+
+       status = libinput_device_config_middle_emulation_set_enabled(device,
+                               LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED);
+
+       if (status == LIBINPUT_CONFIG_STATUS_UNSUPPORTED)
+               return;
+
+       status = libinput_device_config_scroll_set_method(device,
+                                LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN);
+       ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+       status = libinput_device_config_scroll_set_button(device, BTN_MIDDLE);
+       ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+       litest_drain_events(li);
+
+       litest_button_click(dev, BTN_LEFT, 1);
+       litest_button_click(dev, BTN_RIGHT, 1);
+       libinput_dispatch(li);
+       litest_timeout_buttonscroll();
+       libinput_dispatch(li);
+
+       for (i = 0; i < 10; i++) {
+               litest_event(dev, EV_REL, REL_Y, -1);
+               litest_event(dev, EV_SYN, SYN_REPORT, 0);
+       }
+
+       libinput_dispatch(li);
+
+       litest_button_click(dev, BTN_LEFT, 0);
+       litest_button_click(dev, BTN_RIGHT, 0);
+       libinput_dispatch(li);
+
+       litest_assert_scroll(li, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -1);
+       litest_assert_empty_queue(li);
+
+       /* Restore default scroll behavior */
+       libinput_device_config_scroll_set_method(dev->libinput_device,
+               libinput_device_config_scroll_get_default_method(
+                       dev->libinput_device));
+       libinput_device_config_scroll_set_button(dev->libinput_device,
+               libinput_device_config_scroll_get_default_button(
+                       dev->libinput_device));
+}
+END_TEST
+
 START_TEST(pointer_scroll_nowheel_defaults)
 {
        struct litest_device *dev = litest_current_device();
@@ -1600,6 +1652,7 @@ litest_setup_tests(void)
        litest_add_no_device("pointer:button", pointer_seat_button_count);
        litest_add("pointer:scroll", pointer_scroll_wheel, LITEST_WHEEL, 
LITEST_TABLET);
        litest_add("pointer:scroll", pointer_scroll_button, 
LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
+       litest_add("pointer:scroll", pointer_scroll_button_middle_emulation, 
LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY);
        litest_add("pointer:scroll", pointer_scroll_nowheel_defaults, 
LITEST_RELATIVE|LITEST_BUTTON, LITEST_WHEEL);
        litest_add("pointer:scroll", pointer_scroll_natural_defaults, 
LITEST_WHEEL, LITEST_TABLET);
        litest_add("pointer:scroll", pointer_scroll_natural_enable_config, 
LITEST_WHEEL, LITEST_TABLET);
-- 
2.5.5

_______________________________________________
wayland-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to