Gets rid of the dead mouse issue when you move the mouse slowly
-- v3: winewayland: Implement relative motion accumulator
From: Etaash Mathamsetty etaash.mathamsetty@gmail.com
--- dlls/winewayland.drv/wayland_pointer.c | 38 ++++++++++++++++++++------ dlls/winewayland.drv/waylanddrv.h | 6 ++++ 2 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 6c852292c1d..a488b34d448 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -257,6 +257,19 @@ static const struct wl_pointer_listener pointer_listener = pointer_handle_axis_discrete };
+/********************************************************************** + * wayland_motion_delta_to_window + * + * Converts the surface-local delta to window (logical) coordinate delta. + */ +static void wayland_motion_delta_to_window(struct wayland_surface *surface, + double surface_x, double surface_y, + double *window_x, double *window_y) +{ + *window_x = surface_x * surface->window.scale; + *window_y = surface_y * surface->window.scale; +} + static void relative_pointer_v1_relative_motion(void *private, struct zwp_relative_pointer_v1 *zwp_relative_pointer_v1, uint32_t utime_hi, uint32_t utime_lo, @@ -265,28 +278,33 @@ static void relative_pointer_v1_relative_motion(void *private, { INPUT input = {0}; HWND hwnd; - POINT screen; + struct wayland_point screen = {0.0}, *d_accum = private; struct wayland_win_data *data;
if (!(hwnd = wayland_pointer_get_focused_hwnd())) return; if (!(data = wayland_win_data_get(hwnd))) return; + if (!private) return;
- wayland_surface_coords_to_window(data->wayland_surface, + wayland_motion_delta_to_window(data->wayland_surface, wl_fixed_to_double(dx), wl_fixed_to_double(dy), - (int *)&screen.x, (int *)&screen.y); - + &screen.x, &screen.y); wayland_win_data_release(data);
+ d_accum->x += screen.x; + d_accum->y += screen.y;
input.type = INPUT_MOUSE; - input.mi.dx = screen.x; - input.mi.dy = screen.y; + input.mi.dx = round(d_accum->x); + input.mi.dy = round(d_accum->y); input.mi.dwFlags = MOUSEEVENTF_MOVE;
- TRACE("hwnd=%p wayland_dxdy=%.2f,%.2f screen_dxdy=%d,%d\n", + TRACE("hwnd=%p wayland_dxdy=%.2f,%.2f accum_dxdy=%d,%d\n", hwnd, wl_fixed_to_double(dx), wl_fixed_to_double(dy), - (int)screen.x, (int)screen.y); + input.mi.dx, input.mi.dy); + + d_accum->x -= input.mi.dx; + d_accum->y -= input.mi.dy;
NtUserSendHardwareInput(hwnd, 0, &input, 0); } @@ -679,6 +697,7 @@ static void wayland_pointer_update_constraint(struct wl_surface *wl_surface, struct wayland_pointer *pointer = &process_wayland.pointer; BOOL needs_relative, needs_lock, needs_confine; static unsigned int once; + static struct wayland_point accum = {0.0};
if (!process_wayland.zwp_pointer_constraints_v1) { @@ -783,11 +802,12 @@ static void wayland_pointer_update_constraint(struct wl_surface *wl_surface, process_wayland.zwp_relative_pointer_manager_v1, pointer->wl_pointer); zwp_relative_pointer_v1_add_listener(pointer->zwp_relative_pointer_v1, - &relative_pointer_v1_listener, NULL); + &relative_pointer_v1_listener, &accum); TRACE("Enabling relative motion\n"); } else if (!needs_relative && pointer->zwp_relative_pointer_v1) { + memset(&accum, 0, sizeof(accum)); zwp_relative_pointer_v1_destroy(pointer->zwp_relative_pointer_v1); pointer->zwp_relative_pointer_v1 = NULL; TRACE("Disabling relative motion\n"); diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 50d5fc44079..d50285a2a05 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -92,6 +92,12 @@ struct wayland_keyboard pthread_mutex_t mutex; };
+struct wayland_point +{ + double x; + double y; +}; + struct wayland_cursor { struct wayland_shm_buffer *shm_buffer;
Turns out winex11 solved the problem in literally the same way