mirror of
https://github.com/labwc/labwc.git
synced 2026-03-11 05:33:49 -04:00
cursor: prevent hi-res mice triggering scroll actions too often
Hi-res mice produces mulitple scroll events with `delta_discrete` != 0 during a single "click". This patch makes them trigger `Scroll` actions only when the accumulated `delta_discrete` exceeds 120 (= 1 click). See https://lists.freedesktop.org/archives/wayland-devel/2019-April/040377.html for how hi-res scroll events are reported.
This commit is contained in:
parent
1747d9e961
commit
cb79eccea1
2 changed files with 42 additions and 40 deletions
|
|
@ -111,9 +111,10 @@ struct seat {
|
||||||
bool cursor_visible;
|
bool cursor_visible;
|
||||||
struct wlr_cursor *cursor;
|
struct wlr_cursor *cursor;
|
||||||
struct wlr_xcursor_manager *xcursor_manager;
|
struct wlr_xcursor_manager *xcursor_manager;
|
||||||
struct {
|
struct accumulated_scroll {
|
||||||
double x, y;
|
double delta;
|
||||||
} smooth_scroll_offset;
|
double delta_discrete;
|
||||||
|
} accumulated_scrolls[2]; /* indexed by wl_pointer_axis */
|
||||||
bool cursor_scroll_wheel_emulation;
|
bool cursor_scroll_wheel_emulation;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1245,38 +1245,44 @@ struct scroll_info {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct scroll_info
|
static struct scroll_info
|
||||||
compare_delta(double delta, double delta_discrete, double *accum)
|
compare_delta(double delta, double delta_discrete, struct accumulated_scroll *accum)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* Smooth scroll deltas are in surface space, so treating each unit as a
|
|
||||||
* scroll event would result in too-fast scrolling.
|
|
||||||
*
|
|
||||||
* This fudge factor (inherited from various historic projects, incl. Weston)
|
|
||||||
* produces events at a more reasonable rate.
|
|
||||||
*
|
|
||||||
* For historic context, see:
|
|
||||||
* https://lists.freedesktop.org/archives/wayland-devel/2019-April/040377.html
|
|
||||||
*/
|
|
||||||
const double SCROLL_THRESHOLD = 10.0;
|
|
||||||
struct scroll_info info = {0};
|
struct scroll_info info = {0};
|
||||||
|
|
||||||
if (delta_discrete < 0 || delta < 0) {
|
if (delta_discrete) {
|
||||||
info.direction = -1;
|
/* mice */
|
||||||
} else if (delta_discrete > 0 || delta > 0) {
|
info.direction = delta_discrete > 0 ? 1 : -1;
|
||||||
info.direction = 1;
|
accum->delta_discrete += delta_discrete;
|
||||||
}
|
/*
|
||||||
|
* Non-hi-res mice produce delta_discrete of ±120 for every
|
||||||
if (delta == 0.0) {
|
* "click", so it always triggers actions. But for hi-res mice
|
||||||
/* Delta 0 marks the end of a scroll */
|
* that produce smaller delta_discrete, we accumulate it and
|
||||||
*accum = 0.0;
|
* run actions after it exceeds 120(= 1 click).
|
||||||
|
*/
|
||||||
|
if (fabs(accum->delta_discrete) >= 120.0) {
|
||||||
|
accum->delta_discrete = fmod(accum->delta_discrete, 120.0);
|
||||||
|
info.run_action = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Accumulate smooth scrolling until we hit threshold */
|
/* 2-finger scrolling on touchpads */
|
||||||
*accum += delta;
|
if (delta == 0) {
|
||||||
}
|
/* delta=0 marks the end of a scroll */
|
||||||
|
accum->delta = 0;
|
||||||
if (delta_discrete != 0 || fabs(*accum) > SCROLL_THRESHOLD) {
|
return info;
|
||||||
*accum = fmod(*accum, SCROLL_THRESHOLD);
|
}
|
||||||
info.run_action = true;
|
info.direction = delta > 0 ? 1 : -1;
|
||||||
|
accum->delta += delta;
|
||||||
|
/*
|
||||||
|
* The threshold of 10 is inherited from various historic
|
||||||
|
* projects including weston.
|
||||||
|
*
|
||||||
|
* For historic context, see:
|
||||||
|
* https://lists.freedesktop.org/archives/wayland-devel/2019-April/040377.html
|
||||||
|
*/
|
||||||
|
if (fabs(accum->delta) >= 10.0) {
|
||||||
|
accum->delta = fmod(accum->delta, 10.0);
|
||||||
|
info.run_action = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
|
|
@ -1290,21 +1296,16 @@ process_cursor_axis(struct server *server, enum wl_pointer_axis orientation,
|
||||||
uint32_t modifiers = keyboard_get_all_modifiers(&server->seat);
|
uint32_t modifiers = keyboard_get_all_modifiers(&server->seat);
|
||||||
|
|
||||||
enum direction direction = LAB_DIRECTION_INVALID;
|
enum direction direction = LAB_DIRECTION_INVALID;
|
||||||
struct scroll_info info = {0};
|
struct scroll_info info = compare_delta(delta, delta_discrete,
|
||||||
|
&server->seat.accumulated_scrolls[orientation]);
|
||||||
|
|
||||||
if (orientation == WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
|
if (orientation == WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
|
||||||
info = compare_delta(delta, delta_discrete,
|
|
||||||
&server->seat.smooth_scroll_offset.x);
|
|
||||||
|
|
||||||
if (info.direction < 0) {
|
if (info.direction < 0) {
|
||||||
direction = LAB_DIRECTION_LEFT;
|
direction = LAB_DIRECTION_LEFT;
|
||||||
} else if (info.direction > 0) {
|
} else if (info.direction > 0) {
|
||||||
direction = LAB_DIRECTION_RIGHT;
|
direction = LAB_DIRECTION_RIGHT;
|
||||||
}
|
}
|
||||||
} else if (orientation == WL_POINTER_AXIS_VERTICAL_SCROLL) {
|
} else if (orientation == WL_POINTER_AXIS_VERTICAL_SCROLL) {
|
||||||
info = compare_delta(delta, delta_discrete,
|
|
||||||
&server->seat.smooth_scroll_offset.y);
|
|
||||||
|
|
||||||
if (info.direction < 0) {
|
if (info.direction < 0) {
|
||||||
direction = LAB_DIRECTION_UP;
|
direction = LAB_DIRECTION_UP;
|
||||||
} else if (info.direction > 0) {
|
} else if (info.direction > 0) {
|
||||||
|
|
@ -1324,8 +1325,8 @@ process_cursor_axis(struct server *server, enum wl_pointer_axis orientation,
|
||||||
&& mousebind->mouse_event == MOUSE_ACTION_SCROLL) {
|
&& mousebind->mouse_event == MOUSE_ACTION_SCROLL) {
|
||||||
handled = true;
|
handled = true;
|
||||||
/*
|
/*
|
||||||
* Action may not be executed if the accumulated scroll
|
* Action may not be executed if the accumulated scroll delta
|
||||||
* delta on touchpads doesn't exceed the threshold
|
* on touchpads or hi-res mice doesn't exceed the threshold
|
||||||
*/
|
*/
|
||||||
if (info.run_action) {
|
if (info.run_action) {
|
||||||
actions_run(ctx.view, server, &mousebind->actions, &ctx);
|
actions_run(ctx.view, server, &mousebind->actions, &ctx);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue