diff --git a/src/evdev-debounce.c b/src/evdev-debounce.c index 9864cac2..0c520c8c 100644 --- a/src/evdev-debounce.c +++ b/src/evdev-debounce.c @@ -176,7 +176,7 @@ debounce_notify_button(struct fallback_dispatch *fallback, code = evdev_to_left_handed(device, code); - evdev_pointer_notify_physical_button(device, time, code, state); + fallback_notify_physical_button(fallback, device, time, code, state); } static void diff --git a/src/evdev-fallback.c b/src/evdev-fallback.c index f24db171..71e610f0 100644 --- a/src/evdev-fallback.c +++ b/src/evdev-fallback.c @@ -61,6 +61,19 @@ fallback_lid_notify_toggle(struct fallback_dispatch *dispatch, } } +void +fallback_notify_physical_button(struct fallback_dispatch *dispatch, + struct evdev_device *device, + uint64_t time, + int button, + enum libinput_button_state state) +{ + if (button == BTN_MIDDLE) + dispatch->wheel.is_inhibited = (state == LIBINPUT_BUTTON_STATE_PRESSED); + + evdev_pointer_notify_physical_button(device, time, button, state); +} + static enum libinput_switch_state fallback_interface_get_switch_state(struct evdev_dispatch *evdev_dispatch, enum libinput_switch sw) @@ -212,6 +225,12 @@ fallback_flush_wheels(struct fallback_dispatch *dispatch, if (!(device->seat_caps & EVDEV_DEVICE_POINTER)) return; + if (dispatch->wheel.is_inhibited) { + dispatch->wheel.delta.x = 0; + dispatch->wheel.delta.y = 0; + return; + } + if (device->model_flags & EVDEV_MODEL_LENOVO_SCROLLPOINT) { struct normalized_coords unaccel = { 0.0, 0.0 }; diff --git a/src/evdev-fallback.h b/src/evdev-fallback.h index 5ab9d352..58f32426 100644 --- a/src/evdev-fallback.h +++ b/src/evdev-fallback.h @@ -99,6 +99,7 @@ struct fallback_dispatch { struct { struct device_coords delta; + bool is_inhibited; } wheel; struct { @@ -244,5 +245,11 @@ get_key_down_count(struct evdev_device *device, int code) void fallback_init_debounce(struct fallback_dispatch *dispatch); void fallback_debounce_handle_state(struct fallback_dispatch *dispatch, uint64_t time); +void +fallback_notify_physical_button(struct fallback_dispatch *dispatch, + struct evdev_device *device, + uint64_t time, + int button, + enum libinput_button_state state); #endif diff --git a/test/test-pointer.c b/test/test-pointer.c index da3ee190..a4be655a 100644 --- a/test/test-pointer.c +++ b/test/test-pointer.c @@ -675,6 +675,30 @@ START_TEST(pointer_scroll_wheel) } END_TEST +START_TEST(pointer_scroll_wheel_pressed_noscroll) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + + litest_drain_events(li); + + litest_button_click_debounced(dev, li, BTN_MIDDLE, true); + litest_drain_events(li); + + for (int i = 0; i < 10; i++) { + litest_event(dev, EV_REL, REL_WHEEL, 1); + litest_event(dev, EV_REL, REL_HWHEEL, 1); + litest_event(dev, EV_SYN, SYN_REPORT, 0); + } + + libinput_dispatch(li); + + litest_assert_empty_queue(li); + + litest_button_click_debounced(dev, li, BTN_MIDDLE, false); +} +END_TEST + START_TEST(pointer_scroll_natural_defaults) { struct litest_device *dev = litest_current_device(); @@ -3141,6 +3165,7 @@ TEST_COLLECTION(pointer) litest_add_for_device(pointer_button_has_no_button, LITEST_KEYBOARD); litest_add(pointer_recover_from_lost_button_count, LITEST_BUTTON, LITEST_CLICKPAD); litest_add(pointer_scroll_wheel, LITEST_WHEEL, LITEST_TABLET); + litest_add_for_device(pointer_scroll_wheel_pressed_noscroll, LITEST_MOUSE); litest_add(pointer_scroll_button, LITEST_RELATIVE|LITEST_BUTTON, LITEST_ANY); litest_add(pointer_scroll_button_noscroll, LITEST_ABSOLUTE|LITEST_BUTTON, LITEST_RELATIVE); litest_add(pointer_scroll_button_noscroll, LITEST_ANY, LITEST_RELATIVE|LITEST_BUTTON);