From 08d31145fd100f474119e37528e4021e60e722ed Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Sat, 11 Jan 2025 23:36:58 +0900 Subject: [PATCH] cursor: don't leak bound scroll events from touchpad to clients Prior to this commit, when we receive fine-grained scroll events from touchpads that are bound to any mousebind, we leaked the scroll events to the client unless the accumulated scroll delta exceeds the fixed threshold. This was annoying for example when a user wants to ZoomIn/Out with W-Up/Down mousebinds with a touchpad. So this commit fixes it by not leaking the scroll events nor executing actions when the accumulated delta doesn't exceed the threshold. --- src/input/cursor.c | 47 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/input/cursor.c b/src/input/cursor.c index 538afd80..5af3bd0e 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -1246,7 +1246,12 @@ cursor_emulate_button(struct seat *seat, uint32_t button, wlr_seat_pointer_notify_frame(seat->seat); } -static int +struct scroll_info { + int direction; + bool run_action; +}; + +static struct scroll_info compare_delta(const struct wlr_pointer_axis_event *event, double *accum) { /* @@ -1260,6 +1265,13 @@ compare_delta(const struct wlr_pointer_axis_event *event, double *accum) * https://lists.freedesktop.org/archives/wayland-devel/2019-April/040377.html */ const double SCROLL_THRESHOLD = 10.0; + struct scroll_info info = {0}; + + if (event->delta_discrete < 0 || event->delta < 0) { + info.direction = -1; + } else if (event->delta_discrete > 0 || event->delta > 0) { + info.direction = 1; + } if (event->delta == 0.0) { /* Delta 0 marks the end of a scroll */ @@ -1268,14 +1280,13 @@ compare_delta(const struct wlr_pointer_axis_event *event, double *accum) /* Accumulate smooth scrolling until we hit threshold */ *accum += event->delta; } - if (event->delta_discrete < 0 || *accum < -SCROLL_THRESHOLD) { + + if (event->delta_discrete != 0 || fabs(*accum) > SCROLL_THRESHOLD) { *accum = fmod(*accum, SCROLL_THRESHOLD); - return -1; - } else if (event->delta_discrete > 0 || *accum > SCROLL_THRESHOLD) { - *accum = fmod(*accum, SCROLL_THRESHOLD); - return 1; + info.run_action = true; } - return 0; + + return info; } static bool @@ -1287,18 +1298,20 @@ handle_cursor_axis(struct server *server, struct cursor_context *ctx, uint32_t modifiers = keyboard_get_all_modifiers(&server->seat); enum direction direction = LAB_DIRECTION_INVALID; + struct scroll_info info = {0}; + if (event->orientation == WL_POINTER_AXIS_HORIZONTAL_SCROLL) { - int rel = compare_delta(event, &server->seat.smooth_scroll_offset.x); - if (rel < 0) { + info = compare_delta(event, &server->seat.smooth_scroll_offset.x); + if (info.direction < 0) { direction = LAB_DIRECTION_LEFT; - } else if (rel > 0) { + } else if (info.direction > 0) { direction = LAB_DIRECTION_RIGHT; } } else if (event->orientation == WL_POINTER_AXIS_VERTICAL_SCROLL) { - int rel = compare_delta(event, &server->seat.smooth_scroll_offset.y); - if (rel < 0) { + info = compare_delta(event, &server->seat.smooth_scroll_offset.y); + if (info.direction < 0) { direction = LAB_DIRECTION_UP; - } else if (rel > 0) { + } else if (info.direction > 0) { direction = LAB_DIRECTION_DOWN; } } else { @@ -1315,7 +1328,13 @@ handle_cursor_axis(struct server *server, struct cursor_context *ctx, && modifiers == mousebind->modifiers && mousebind->mouse_event == MOUSE_ACTION_SCROLL) { handled = true; - actions_run(ctx->view, server, &mousebind->actions, ctx); + /* + * Action may not be executed if the accumulated scroll + * delta on touchpads doesn't exceed the threshold + */ + if (info.run_action) { + actions_run(ctx->view, server, &mousebind->actions, ctx); + } } }