From: Etaash Mathamsetty etaash.mathamsetty@gmail.com
--- dlls/winewayland.drv/wayland_pointer.c | 53 ++++++++++++++++++++------ dlls/winewayland.drv/waylanddrv.h | 2 + 2 files changed, 43 insertions(+), 12 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 6c852292c1d..2a175b8f3c2 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,41 @@ static void relative_pointer_v1_relative_motion(void *private, { INPUT input = {0}; HWND hwnd; - POINT screen; + struct { + double x; + double y; + } screen = {0.0}; + struct wayland_pointer *pointer = 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, - wl_fixed_to_double(dx), - wl_fixed_to_double(dy), - (int *)&screen.x, (int *)&screen.y); - + wayland_motion_delta_to_window(data->wayland_surface, + wl_fixed_to_double(dx), + wl_fixed_to_double(dy), + &screen.x, &screen.y); wayland_win_data_release(data);
+ pthread_mutex_lock(&pointer->mutex); + + pointer->accum_x += screen.x; + pointer->accum_y += screen.y;
input.type = INPUT_MOUSE; - input.mi.dx = screen.x; - input.mi.dy = screen.y; + input.mi.dx = round(pointer->accum_x); + input.mi.dy = round(pointer->accum_y); input.mi.dwFlags = MOUSEEVENTF_MOVE;
- TRACE("hwnd=%p wayland_dxdy=%.2f,%.2f screen_dxdy=%d,%d\n", - hwnd, wl_fixed_to_double(dx), wl_fixed_to_double(dy), - (int)screen.x, (int)screen.y); + pointer->accum_x -= input.mi.dx; + pointer->accum_y -= input.mi.dy; + + pthread_mutex_unlock(&pointer->mutex); + + TRACE("hwnd=%p wayland_dxdy=%.2f,%.2f accum_dxdy=%d,%d\n", + hwnd, wl_fixed_to_double(dx), wl_fixed_to_double(dy), + input.mi.dx, input.mi.dy);
NtUserSendHardwareInput(hwnd, 0, &input, 0); } @@ -783,11 +809,14 @@ 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, pointer); TRACE("Enabling relative motion\n"); } else if (!needs_relative && pointer->zwp_relative_pointer_v1) { + pthread_mutex_lock(&pointer->mutex); + pointer->accum_x = pointer->accum_y = 0; + pthread_mutex_unlock(&pointer->mutex); 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..30fc65d949a 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -112,6 +112,8 @@ struct wayland_pointer uint32_t enter_serial; uint32_t button_serial; struct wayland_cursor cursor; + double accum_x; + double accum_y; pthread_mutex_t mutex; };