mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-04-25 08:44:13 +00:00
wayland: Special-case relative warp mode to deliver accelerated relative motion
The Wayland backend lacks pointer warp functionality, so special-case the relative warp mode hint to deliver accelerated relative motion deltas, which is ultimately what the client wants by enabling this hint.
(cherry picked from commit 235e4870af)
This commit is contained in:
@@ -1121,6 +1121,15 @@ int SDL_WarpMouseGlobal(int x, int y)
|
||||
|
||||
static SDL_bool ShouldUseRelativeModeWarp(SDL_Mouse *mouse)
|
||||
{
|
||||
#ifdef SDL_VIDEO_DRIVER_WAYLAND
|
||||
SDL_VideoDevice *vid = SDL_GetVideoDevice();
|
||||
|
||||
/* Wayland can't warp the mouse, but uses this hint internally to deliver accelerated motion */
|
||||
if (SDL_strcmp(vid->name, "wayland") == 0) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!mouse->WarpMouse) {
|
||||
/* Need this functionality for relative mode warp implementation */
|
||||
return SDL_FALSE;
|
||||
|
||||
@@ -2681,23 +2681,28 @@ static void relative_pointer_handle_relative_motion(void *data,
|
||||
struct SDL_WaylandInput *input = data;
|
||||
SDL_VideoData *d = input->display;
|
||||
SDL_WindowData *window = input->pointer_focus;
|
||||
double dx_unaccel;
|
||||
double dy_unaccel;
|
||||
double dx;
|
||||
double dy;
|
||||
double dx_mod;
|
||||
double dy_mod;
|
||||
|
||||
dx_unaccel = wl_fixed_to_double(dx_unaccel_w);
|
||||
dy_unaccel = wl_fixed_to_double(dy_unaccel_w);
|
||||
if (!d->relative_mode_accelerated) {
|
||||
dx = wl_fixed_to_double(dx_unaccel_w);
|
||||
dy = wl_fixed_to_double(dy_unaccel_w);
|
||||
} else {
|
||||
dx = wl_fixed_to_double(dx_w) * (window ? window->pointer_scale_x : 1.0);
|
||||
dy = wl_fixed_to_double(dy_w) * (window ? window->pointer_scale_y : 1.0);
|
||||
}
|
||||
|
||||
/* Add left over fraction from last event. */
|
||||
dx_unaccel += input->dx_frac;
|
||||
dy_unaccel += input->dy_frac;
|
||||
dx += input->dx_frac;
|
||||
dy += input->dy_frac;
|
||||
|
||||
input->dx_frac = modf(dx_unaccel, &dx);
|
||||
input->dy_frac = modf(dy_unaccel, &dy);
|
||||
input->dx_frac = modf(dx, &dx_mod);
|
||||
input->dy_frac = modf(dy, &dy_mod);
|
||||
|
||||
if (input->pointer_focus && d->relative_mouse_mode) {
|
||||
SDL_SendMouseMotion(window->sdlwindow, 0, 1, (int)dx, (int)dy);
|
||||
SDL_SendMouseMotion(window->sdlwindow, 0, 1, (int)dx_mod, (int)dy_mod);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -537,6 +537,9 @@ static int Wayland_SetRelativeMouseMode(SDL_bool enabled)
|
||||
SDL_VideoData *data = (SDL_VideoData *)vd->driverdata;
|
||||
|
||||
if (enabled) {
|
||||
/* Clients use relative warp mode to get accelerated motion deltas, which Wayland delivers internally. */
|
||||
data->relative_mode_accelerated = SDL_GetHintBoolean(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, SDL_FALSE);
|
||||
|
||||
/* Disable mouse warp emulation if it's enabled. */
|
||||
if (data->input->relative_mode_override) {
|
||||
data->input->relative_mode_override = SDL_FALSE;
|
||||
|
||||
@@ -101,6 +101,7 @@ typedef struct
|
||||
char *classname;
|
||||
|
||||
int relative_mouse_mode;
|
||||
int relative_mode_accelerated;
|
||||
SDL_bool egl_transparency_enabled;
|
||||
} SDL_VideoData;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user