1
0
mirror of https://github.com/mpv-player/mpv synced 2025-02-15 11:37:03 +00:00

wayland_common: prefer axis_value120 if supported

Prefer axis_value120 for high resolution scrolling if supported, which
matches the existing win32 behavior.
This commit is contained in:
nanahi 2024-02-01 20:53:19 -05:00 committed by Dudemanguy
parent f95b7146d7
commit b3edb46fd9
2 changed files with 96 additions and 16 deletions

View File

@ -56,6 +56,10 @@
#include "cursor-shape-v1.h"
#endif
#if WAYLAND_VERSION_MAJOR > 1 || WAYLAND_VERSION_MINOR >= 21
#define HAVE_WAYLAND_1_21
#endif
#if WAYLAND_VERSION_MAJOR > 1 || WAYLAND_VERSION_MINOR >= 22
#define HAVE_WAYLAND_1_22
#endif
@ -294,35 +298,95 @@ static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
uint32_t time, uint32_t axis, wl_fixed_t value)
{
struct vo_wayland_state *wl = data;
// The axis value is specified in logical coordinates, but the exact value emitted
// by one mouse wheel click is unspecified. In practice, most compositors use either
// 10 (GNOME, Weston) or 15 (wlroots, same as libinput) as the value.
// Divide the value by 10 and clamp it between -1 and 1 so that mouse wheel clicks
// work as intended on all compositors while still allowing high resolution trackpads.
double val = MPCLAMP(wl_fixed_to_double(value) / 10.0, -1, 1);
switch (axis) {
case WL_POINTER_AXIS_VERTICAL_SCROLL:
if (value > 0)
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_DOWN | wl->mpmod, +val);
if (value < 0)
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_UP | wl->mpmod, -val);
wl->axis_value_vertical += wl_fixed_to_double(value);
break;
case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
if (value > 0)
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_RIGHT | wl->mpmod, +val);
if (value < 0)
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_LEFT | wl->mpmod, -val);
wl->axis_value_horizontal += wl_fixed_to_double(value);
break;
}
}
static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer)
{
struct vo_wayland_state *wl = data;
double value_vertical, value_horizontal;
if (wl->axis_value120_scroll) {
// Prefer axis_value120 if supported and the axis event is from mouse wheel.
value_vertical = wl->axis_value120_vertical / 120.0;
value_horizontal = wl->axis_value120_horizontal / 120.0;
} else {
// The axis value is specified in logical coordinates, but the exact value emitted
// by one mouse wheel click is unspecified. In practice, most compositors use either
// 10 (GNOME, Weston) or 15 (wlroots, same as libinput) as the value.
// Divide the value by 10 and clamp it between -1 and 1 so that mouse wheel clicks
// work as intended on all compositors while still allowing high resolution trackpads.
value_vertical = MPCLAMP(wl->axis_value_vertical / 10.0, -1, 1);
value_horizontal = MPCLAMP(wl->axis_value_horizontal / 10.0, -1, 1);
}
if (value_vertical > 0)
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_DOWN | wl->mpmod, +value_vertical);
if (value_vertical < 0)
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_UP | wl->mpmod, -value_vertical);
if (value_horizontal > 0)
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_RIGHT | wl->mpmod, +value_horizontal);
if (value_horizontal < 0)
mp_input_put_wheel(wl->vo->input_ctx, MP_WHEEL_LEFT | wl->mpmod, -value_horizontal);
wl->axis_value120_scroll = false;
wl->axis_value_vertical = 0;
wl->axis_value_horizontal = 0;
wl->axis_value120_vertical = 0;
wl->axis_value120_horizontal = 0;
}
static void pointer_handle_axis_source(void *data, struct wl_pointer *wl_pointer,
uint32_t axis_source)
{
}
static void pointer_handle_axis_stop(void *data, struct wl_pointer *wl_pointer,
uint32_t time, uint32_t axis)
{
}
static void pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_pointer,
uint32_t axis, int32_t discrete)
{
}
#ifdef HAVE_WAYLAND_1_21
static void pointer_handle_axis_value120(void *data, struct wl_pointer *wl_pointer,
uint32_t axis, int32_t value120)
{
struct vo_wayland_state *wl = data;
wl->axis_value120_scroll = true;
switch (axis) {
case WL_POINTER_AXIS_VERTICAL_SCROLL:
wl->axis_value120_vertical += value120;
break;
case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
wl->axis_value120_horizontal += value120;
break;
}
}
#endif
static const struct wl_pointer_listener pointer_listener = {
pointer_handle_enter,
pointer_handle_leave,
pointer_handle_motion,
pointer_handle_button,
pointer_handle_axis,
pointer_handle_frame,
pointer_handle_axis_source,
pointer_handle_axis_stop,
pointer_handle_axis_discrete,
#ifdef HAVE_WAYLAND_1_21
pointer_handle_axis_value120,
#endif
};
static void touch_handle_down(void *data, struct wl_touch *wl_touch,
@ -534,8 +598,14 @@ static void seat_handle_caps(void *data, struct wl_seat *seat,
}
}
static void seat_handle_name(void *data, struct wl_seat *seat,
const char *name)
{
}
static const struct wl_seat_listener seat_listener = {
seat_handle_caps,
seat_handle_name,
};
static void data_offer_handle_offer(void *data, struct wl_data_offer *offer,
@ -1338,7 +1408,12 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id
}
if (!strcmp(interface, wl_seat_interface.name) && found++) {
wl->seat = wl_registry_bind(reg, id, &wl_seat_interface, 1);
#ifdef HAVE_WAYLAND_1_21
ver = MPMIN(ver, 8); /* Cap at 8 in case new events are added later. */
#else
ver = MPMIN(ver, 7);
#endif
wl->seat = wl_registry_bind(reg, id, &wl_seat_interface, ver);
wl_seat_add_listener(wl->seat, &seat_listener, wl);
}

View File

@ -151,6 +151,11 @@ struct vo_wayland_state {
uint32_t keyboard_code;
int mpkey;
int mpmod;
double axis_value_vertical;
int32_t axis_value120_vertical;
double axis_value_horizontal;
int32_t axis_value120_horizontal;
bool axis_value120_scroll;
/* DND */
struct wl_data_device *dnd_ddev;