mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
input: implement wl_pointer::axis_value120()
This implements high resolution mouse wheel scroll events. A "normal" scroll step corresponds to the value 120. Anything less than that is a partial scroll step. This event replaces axis_discrete(), when we bind wl_seat v8 (which we now do, when available). We calculate the number of degrees that is required to scroll a single line, based off of the scrollback.multiplier value. Each high-res event accumulates, until we have at least the number of degress required to scroll one, or more lines. The remaining degrees are kept, and added to in the next scroll event. Closes #1738
This commit is contained in:
parent
f3d848da01
commit
aea16ba5d2
4 changed files with 69 additions and 13 deletions
|
|
@ -60,8 +60,10 @@
|
|||
* Support for `wp_single_pixel_buffer_v1`; certain overlay surfaces
|
||||
will now utilize the new single-pixel buffer protocol. This mainly
|
||||
reduces the memory usage, but should also be slightly faster.
|
||||
* Support for high-res mouse wheel scroll events ([#1738][1738]).
|
||||
|
||||
[1707]: https://codeberg.org/dnkl/foot/issues/1707
|
||||
[1738]: https://codeberg.org/dnkl/foot/issues/1738
|
||||
|
||||
|
||||
### Changed
|
||||
|
|
|
|||
71
input.c
71
input.c
|
|
@ -2768,7 +2768,7 @@ mouse_scroll(struct seat *seat, int amount, enum wl_pointer_axis axis)
|
|||
}
|
||||
}
|
||||
|
||||
static float
|
||||
static double
|
||||
mouse_scroll_multiplier(const struct terminal *term, const struct seat *seat)
|
||||
{
|
||||
return (term->grid == &term->normal ||
|
||||
|
|
@ -2812,15 +2812,15 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer,
|
|||
|
||||
static void
|
||||
wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer,
|
||||
uint32_t axis, int32_t discrete)
|
||||
enum wl_pointer_axis axis, int32_t discrete)
|
||||
{
|
||||
LOG_DBG("axis_discrete: %d", discrete);
|
||||
struct seat *seat = data;
|
||||
|
||||
if (touch_is_active(seat))
|
||||
return;
|
||||
|
||||
seat->mouse.have_discrete = true;
|
||||
|
||||
int amount = discrete;
|
||||
|
||||
if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) {
|
||||
|
|
@ -2831,6 +2831,50 @@ wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer,
|
|||
mouse_scroll(seat, amount, axis);
|
||||
}
|
||||
|
||||
#if defined(WL_POINTER_AXIS_VALUE120_SINCE_VERSION)
|
||||
static void
|
||||
wl_pointer_axis_value120(void *data, struct wl_pointer *wl_pointer,
|
||||
enum wl_pointer_axis axis, int32_t value120)
|
||||
{
|
||||
LOG_DBG("axis_value120: %d -> %.2f", value120, (float)value120 / 120.);
|
||||
|
||||
struct seat *seat = data;
|
||||
|
||||
if (touch_is_active(seat))
|
||||
return;
|
||||
|
||||
seat->mouse.have_discrete = true;
|
||||
|
||||
/*
|
||||
* 120 corresponds to a single "low-res" scroll step.
|
||||
*
|
||||
* When doing high-res scrolling, take the scrollback.multiplier,
|
||||
* and calculate how many degrees there are per line.
|
||||
*
|
||||
* For example, with scrollback.multiplier = 3, we have 120 / 3 == 40.
|
||||
*
|
||||
* Then, accumulate high-res scroll events, until we have *at
|
||||
* least* that much. Translate the accumulated value to number of
|
||||
* lines, and scroll.
|
||||
*
|
||||
* Subtract the "used" degrees from the accumulated value, and
|
||||
* keep what's left (this value will always be less than the
|
||||
* per-line value).
|
||||
*/
|
||||
const double multiplier = mouse_scroll_multiplier(seat->mouse_focus, seat);
|
||||
const double per_line = 120. / multiplier;
|
||||
|
||||
seat->mouse.aggregated_120[axis] += (double)value120;
|
||||
|
||||
if (fabs(seat->mouse.aggregated_120[axis]) < per_line)
|
||||
return;
|
||||
|
||||
int lines = (int)(seat->mouse.aggregated_120[axis] / per_line);
|
||||
mouse_scroll(seat, lines, axis);
|
||||
seat->mouse.aggregated_120[axis] -= (double)lines * per_line;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
wl_pointer_frame(void *data, struct wl_pointer *wl_pointer)
|
||||
{
|
||||
|
|
@ -2862,15 +2906,18 @@ wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer,
|
|||
}
|
||||
|
||||
const struct wl_pointer_listener pointer_listener = {
|
||||
.enter = wl_pointer_enter,
|
||||
.leave = wl_pointer_leave,
|
||||
.motion = wl_pointer_motion,
|
||||
.button = wl_pointer_button,
|
||||
.axis = wl_pointer_axis,
|
||||
.frame = wl_pointer_frame,
|
||||
.axis_source = wl_pointer_axis_source,
|
||||
.axis_stop = wl_pointer_axis_stop,
|
||||
.axis_discrete = wl_pointer_axis_discrete,
|
||||
.enter = &wl_pointer_enter,
|
||||
.leave = &wl_pointer_leave,
|
||||
.motion = &wl_pointer_motion,
|
||||
.button = &wl_pointer_button,
|
||||
.axis = &wl_pointer_axis,
|
||||
.frame = &wl_pointer_frame,
|
||||
.axis_source = &wl_pointer_axis_source,
|
||||
.axis_stop = &wl_pointer_axis_stop,
|
||||
.axis_discrete = &wl_pointer_axis_discrete,
|
||||
#if defined(WL_POINTER_AXIS_VALUE120_SINCE_VERSION)
|
||||
.axis_value120 = &wl_pointer_axis_value120,
|
||||
#endif
|
||||
};
|
||||
|
||||
static bool
|
||||
|
|
|
|||
|
|
@ -1161,6 +1161,12 @@ handle_global(void *data, struct wl_registry *registry,
|
|||
if (!verify_iface_version(interface, version, required))
|
||||
return;
|
||||
|
||||
#if defined(WL_POINTER_AXIS_VALUE120_SINCE_VERSION)
|
||||
const uint32_t preferred = WL_POINTER_AXIS_VALUE120_SINCE_VERSION;
|
||||
#else
|
||||
const uint32_t preferred = required;
|
||||
#endif
|
||||
|
||||
int repeat_fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK);
|
||||
if (repeat_fd == -1) {
|
||||
LOG_ERRNO("failed to create keyboard repeat timer FD");
|
||||
|
|
@ -1168,7 +1174,7 @@ handle_global(void *data, struct wl_registry *registry,
|
|||
}
|
||||
|
||||
struct wl_seat *wl_seat = wl_registry_bind(
|
||||
wayl->registry, name, &wl_seat_interface, required);
|
||||
wayl->registry, name, &wl_seat_interface, min(version, preferred));
|
||||
|
||||
tll_push_back(wayl->seats, ((struct seat){
|
||||
.wayl = wayl,
|
||||
|
|
|
|||
|
|
@ -192,6 +192,7 @@ struct seat {
|
|||
|
||||
/* We used a discrete axis event in the current pointer frame */
|
||||
double aggregated[2];
|
||||
double aggregated_120[2];
|
||||
bool have_discrete;
|
||||
} mouse;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue