#define WHEEL_SCROLL_TIMEOUT ms2us(500)
enum wheel_event {
- WHEEL_EVENT_PRESS,
- WHEEL_EVENT_RELEASE,
WHEEL_EVENT_SCROLL_ACCUMULATED,
WHEEL_EVENT_SCROLL,
WHEEL_EVENT_SCROLL_TIMEOUT,
{
switch(state) {
CASE_RETURN_STRING(WHEEL_STATE_NONE);
- CASE_RETURN_STRING(WHEEL_STATE_PRESSED);
CASE_RETURN_STRING(WHEEL_STATE_ACCUMULATING_SCROLL);
CASE_RETURN_STRING(WHEEL_STATE_SCROLLING);
}
wheel_event_to_str(enum wheel_event event)
{
switch(event) {
- CASE_RETURN_STRING(WHEEL_EVENT_PRESS);
- CASE_RETURN_STRING(WHEEL_EVENT_RELEASE);
CASE_RETURN_STRING(WHEEL_EVENT_SCROLL_ACCUMULATED);
CASE_RETURN_STRING(WHEEL_EVENT_SCROLL);
CASE_RETURN_STRING(WHEEL_EVENT_SCROLL_TIMEOUT);
uint64_t time)
{
switch (event) {
- case WHEEL_EVENT_PRESS:
- dispatch->wheel.state = WHEEL_STATE_PRESSED;
- break;
case WHEEL_EVENT_SCROLL:
dispatch->wheel.state = WHEEL_STATE_ACCUMULATING_SCROLL;
break;
case WHEEL_EVENT_SCROLL_DIR_CHANGED:
break;
- case WHEEL_EVENT_RELEASE:
- case WHEEL_EVENT_SCROLL_ACCUMULATED:
- case WHEEL_EVENT_SCROLL_TIMEOUT:
- log_wheel_bug(dispatch, event);
- break;
- }
-}
-
-static void
-wheel_handle_event_on_state_pressed(struct fallback_dispatch *dispatch,
- enum wheel_event event,
- uint64_t time)
-{
- switch (event) {
- case WHEEL_EVENT_RELEASE:
- dispatch->wheel.state = WHEEL_STATE_NONE;
- break;
- case WHEEL_EVENT_SCROLL:
- case WHEEL_EVENT_SCROLL_DIR_CHANGED:
- /* Ignore scroll while the wheel is pressed */
- break;
- case WHEEL_EVENT_PRESS:
case WHEEL_EVENT_SCROLL_ACCUMULATED:
case WHEEL_EVENT_SCROLL_TIMEOUT:
log_wheel_bug(dispatch, event);
uint64_t time)
{
switch (event) {
- case WHEEL_EVENT_PRESS:
- dispatch->wheel.state = WHEEL_STATE_PRESSED;
- break;
case WHEEL_EVENT_SCROLL_ACCUMULATED:
dispatch->wheel.state = WHEEL_STATE_SCROLLING;
wheel_set_scroll_timer(dispatch, time);
case WHEEL_EVENT_SCROLL_DIR_CHANGED:
dispatch->wheel.state = WHEEL_STATE_NONE;
break;
- case WHEEL_EVENT_RELEASE:
case WHEEL_EVENT_SCROLL_TIMEOUT:
log_wheel_bug(dispatch, event);
break;
uint64_t time)
{
switch (event) {
- case WHEEL_EVENT_PRESS:
- dispatch->wheel.state = WHEEL_STATE_PRESSED;
- wheel_cancel_scroll_timer(dispatch);
- break;
case WHEEL_EVENT_SCROLL:
wheel_cancel_scroll_timer(dispatch);
wheel_set_scroll_timer(dispatch, time);
wheel_cancel_scroll_timer(dispatch);
dispatch->wheel.state = WHEEL_STATE_NONE;
break;
- case WHEEL_EVENT_RELEASE:
case WHEEL_EVENT_SCROLL_ACCUMULATED:
log_wheel_bug(dispatch, event);
break;
case WHEEL_STATE_NONE:
wheel_handle_event_on_state_none(dispatch, event, time);
break;
- case WHEEL_STATE_PRESSED:
- wheel_handle_event_on_state_pressed(dispatch, event, time);
- break;
case WHEEL_STATE_ACCUMULATING_SCROLL:
wheel_handle_event_on_state_accumulating_scroll(dispatch,
event,
}
static void
-wheel_handle_state_pressed(struct fallback_dispatch *dispatch,
- struct evdev_device *device,
- uint64_t time)
-{
- dispatch->wheel.hi_res.x = 0;
- dispatch->wheel.hi_res.y = 0;
- dispatch->wheel.lo_res.x = 0;
- dispatch->wheel.lo_res.y = 0;
-}
-
-static void
wheel_handle_state_accumulating_scroll(struct fallback_dispatch *dispatch,
struct evdev_device *device,
uint64_t time)
}
void
-fallback_wheel_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) {
- if (state == LIBINPUT_BUTTON_STATE_PRESSED)
- wheel_handle_event(dispatch, WHEEL_EVENT_PRESS, time);
- else
- wheel_handle_event(dispatch, WHEEL_EVENT_RELEASE, time);
- }
-}
-
-void
fallback_wheel_handle_state(struct fallback_dispatch *dispatch,
struct evdev_device *device,
uint64_t time)
case WHEEL_STATE_NONE:
wheel_handle_state_none(dispatch, device, time);
break;
- case WHEEL_STATE_PRESSED:
- wheel_handle_state_pressed(dispatch, device, time);
- break;
case WHEEL_STATE_ACCUMULATING_SCROLL:
wheel_handle_state_accumulating_scroll(dispatch, device, time);
break;
}
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_hi_res_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_HI_RES, 12);
- litest_event(dev, EV_REL, REL_HWHEEL_HI_RES, 12);
- 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
-
static void
test_hi_res_wheel_event(struct litest_device *dev, int which, int v120_amount)
{
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_for_device(pointer_scroll_hi_res_wheel_pressed_noscroll, LITEST_MOUSE);
litest_add(pointer_scroll_wheel_hires, LITEST_WHEEL, LITEST_TABLET);
litest_add(pointer_scroll_wheel_hires_send_only_lores_vertical, LITEST_WHEEL, LITEST_TABLET);
litest_add(pointer_scroll_wheel_hires_send_only_lores_horizontal, LITEST_WHEEL, LITEST_TABLET);