From: Etaash Mathamsetty etaash.mathamsetty@gmail.com
--- dlls/winewayland.drv/wayland_pointer.c | 46 ++++++++++++++++++++------ dlls/winewayland.drv/waylanddrv.h | 2 ++ 2 files changed, 37 insertions(+), 11 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 6c852292c1d..46d36fe0071 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,38 @@ static void relative_pointer_v1_relative_motion(void *private, { INPUT input = {0}; HWND hwnd; - POINT screen; struct wayland_win_data *data; + double screen_x = 0, screen_y = 0; + struct wayland_pointer *pointer = &process_wayland.pointer;
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); } @@ -788,6 +811,7 @@ static void wayland_pointer_update_constraint(struct wl_surface *wl_surface, } else if (!needs_relative && pointer->zwp_relative_pointer_v1) { + pointer->accum_x = pointer->accum_y = 0; 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; };