mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-20 04:30:06 +01:00
filter: support accelerating high-resolution scroll wheel events
Dispatch high-resolution scroll wheel events through filter_dispatch_scroll so they can be accelerated using the custom acceleration profile. Low-resolution scroll wheel events are not accelerated to avoid zero delta-time in the filter. Signed-off-by: Yinon Burgansky <yinonburgansky@gmail.com> Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1316>
This commit is contained in:
parent
2d4482e03d
commit
94b7836456
1 changed files with 75 additions and 53 deletions
|
|
@ -206,10 +206,6 @@ fallback_flush_wheels(struct fallback_dispatch *dispatch,
|
||||||
struct evdev_device *device,
|
struct evdev_device *device,
|
||||||
uint64_t time)
|
uint64_t time)
|
||||||
{
|
{
|
||||||
struct normalized_coords wheel_degrees = { 0.0, 0.0 };
|
|
||||||
struct discrete_coords discrete = { 0.0, 0.0 };
|
|
||||||
struct wheel_v120 v120 = { 0.0, 0.0 };
|
|
||||||
|
|
||||||
if (!libinput_device_has_capability(&device->base, LIBINPUT_DEVICE_CAP_POINTER))
|
if (!libinput_device_has_capability(&device->base, LIBINPUT_DEVICE_CAP_POINTER))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -238,59 +234,85 @@ fallback_flush_wheels(struct fallback_dispatch *dispatch,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dispatch->wheel.hi_res.y != 0) {
|
/* High-resolution wheel events */
|
||||||
int value = dispatch->wheel.hi_res.y;
|
if (dispatch->wheel.hi_res.x != 0 || dispatch->wheel.hi_res.y != 0) {
|
||||||
|
const struct device_float_coords v120_unaccelerated = {
|
||||||
v120.y = -1 * value;
|
.x = dispatch->wheel.hi_res.x,
|
||||||
wheel_degrees.y =
|
.y = -1 * dispatch->wheel.hi_res.y,
|
||||||
-1 * value / 120.0 * device->scroll.wheel_click_angle.y;
|
};
|
||||||
evdev_notify_axis_wheel(device,
|
const struct normalized_coords v120_accelerated =
|
||||||
time,
|
device->pointer.filter
|
||||||
bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
|
? filter_dispatch_scroll(device->pointer.filter,
|
||||||
&wheel_degrees,
|
&v120_unaccelerated,
|
||||||
&v120);
|
device,
|
||||||
|
time)
|
||||||
|
: (const struct normalized_coords){
|
||||||
|
.x = v120_unaccelerated.x,
|
||||||
|
.y = v120_unaccelerated.y
|
||||||
|
};
|
||||||
|
/* Truncate the fractional part when converting floating-point to
|
||||||
|
integer. This is acceptable because the v120 unit maps one logical
|
||||||
|
click to 120 units; values are effectively measured in 1/120 of a
|
||||||
|
click, so truncation does not lose meaningful resolution. */
|
||||||
|
const struct wheel_v120 v120 = {
|
||||||
|
.x = v120_accelerated.x,
|
||||||
|
.y = v120_accelerated.y,
|
||||||
|
};
|
||||||
|
const struct normalized_coords wheel_degrees = {
|
||||||
|
.x = v120.x / 120.0 * device->scroll.wheel_click_angle.x,
|
||||||
|
.y = v120.y / 120.0 * device->scroll.wheel_click_angle.y,
|
||||||
|
};
|
||||||
|
if (v120.x != 0) {
|
||||||
|
evdev_notify_axis_wheel(
|
||||||
|
device,
|
||||||
|
time,
|
||||||
|
bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL),
|
||||||
|
&wheel_degrees,
|
||||||
|
&v120);
|
||||||
|
}
|
||||||
|
if (v120.y != 0) {
|
||||||
|
evdev_notify_axis_wheel(
|
||||||
|
device,
|
||||||
|
time,
|
||||||
|
bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
|
||||||
|
&wheel_degrees,
|
||||||
|
&v120);
|
||||||
|
}
|
||||||
|
dispatch->wheel.hi_res.x = 0;
|
||||||
dispatch->wheel.hi_res.y = 0;
|
dispatch->wheel.hi_res.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dispatch->wheel.lo_res.y != 0) {
|
/* Low-resolution wheel events */
|
||||||
int value = dispatch->wheel.lo_res.y;
|
if (dispatch->wheel.lo_res.x != 0 || dispatch->wheel.lo_res.y != 0) {
|
||||||
|
/* Do not accelerate low-resolution wheel events: they use different
|
||||||
wheel_degrees.y = -1 * value * device->scroll.wheel_click_angle.y;
|
units than high-resolution events and should not be accelerated with
|
||||||
discrete.y = -1 * value;
|
the same function. */
|
||||||
evdev_notify_axis_legacy_wheel(
|
const struct discrete_coords discrete = {
|
||||||
device,
|
.x = dispatch->wheel.lo_res.x,
|
||||||
time,
|
.y = -1 * dispatch->wheel.lo_res.y,
|
||||||
bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
|
};
|
||||||
&wheel_degrees,
|
const struct normalized_coords wheel_degrees = {
|
||||||
&discrete);
|
.x = discrete.x * device->scroll.wheel_click_angle.x,
|
||||||
dispatch->wheel.lo_res.y = 0;
|
.y = discrete.y * device->scroll.wheel_click_angle.y,
|
||||||
}
|
};
|
||||||
|
if (discrete.x != 0) {
|
||||||
if (dispatch->wheel.hi_res.x != 0) {
|
evdev_notify_axis_legacy_wheel(
|
||||||
int value = dispatch->wheel.hi_res.x;
|
device,
|
||||||
|
time,
|
||||||
v120.x = value;
|
bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL),
|
||||||
wheel_degrees.x = value / 120.0 * device->scroll.wheel_click_angle.x;
|
&wheel_degrees,
|
||||||
evdev_notify_axis_wheel(device,
|
&discrete);
|
||||||
time,
|
}
|
||||||
bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL),
|
if (discrete.y != 0) {
|
||||||
&wheel_degrees,
|
evdev_notify_axis_legacy_wheel(
|
||||||
&v120);
|
device,
|
||||||
dispatch->wheel.hi_res.x = 0;
|
time,
|
||||||
}
|
bit(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL),
|
||||||
|
&wheel_degrees,
|
||||||
if (dispatch->wheel.lo_res.x != 0) {
|
&discrete);
|
||||||
int value = dispatch->wheel.lo_res.x;
|
}
|
||||||
|
|
||||||
wheel_degrees.x = value * device->scroll.wheel_click_angle.x;
|
|
||||||
discrete.x = value;
|
|
||||||
evdev_notify_axis_legacy_wheel(
|
|
||||||
device,
|
|
||||||
time,
|
|
||||||
bit(LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL),
|
|
||||||
&wheel_degrees,
|
|
||||||
&discrete);
|
|
||||||
dispatch->wheel.lo_res.x = 0;
|
dispatch->wheel.lo_res.x = 0;
|
||||||
|
dispatch->wheel.lo_res.y = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue