[PATCH v2 0/5] MR11117: winewayland: Implement pointer rawinput.
Implements rawinput by refactoring a few things and adding a wine staging patch. Also fixes a few bugs with the existing pointer implementation, which can cause the mouse cursor to escape or is just inefficient. As much as I would like to make relative pointer protocol mandatory, most compositors don't support it in their nested mode, which makes this a very difficult tradeoff to make. For now I have left it optional. -- v2: winewayland: Implement pointer rawinput. server: Add send_hardware_message flags for rawinput translation. winewayland: Don't set pointer position hints when unnecessary. winewayland: Do not process motion events with a pending warp. winewayland: Move pointer input processing to frame event. https://gitlab.winehq.org/wine/wine/-/merge_requests/11117
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_pointer.c | 118 +++++++++++++++++-------- dlls/winewayland.drv/waylanddrv.h | 20 ++++- 2 files changed, 100 insertions(+), 38 deletions(-) diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 109dd2dd0eb..82fc15e5343 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -121,9 +121,19 @@ static HWND wayland_pointer_get_focused_hwnd(void) return hwnd; } +static void wayland_pointer_reset_frame(void) +{ + struct wayland_pointer_frame *frame = &process_wayland.pointer.frame; + + frame->dx = frame->dy = 0.0; + frame->horz_scroll = frame->scroll = 0; + frame->flags = 0; +} + static void pointer_handle_motion_internal(wl_fixed_t sx, wl_fixed_t sy) { - INPUT input = {0}; + struct wayland_pointer *pointer = &process_wayland.pointer; + struct wayland_pointer_frame *frame = &pointer->frame; RECT *window_rect; HWND hwnd; POINT screen; @@ -155,16 +165,13 @@ static void pointer_handle_motion_internal(wl_fixed_t sx, wl_fixed_t sy) wayland_win_data_release(data); - input.type = INPUT_MOUSE; - input.mi.dx = screen.x; - input.mi.dy = screen.y; - input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; + frame->x = screen.x; + frame->y = screen.y; + frame->flags |= WAYLAND_POINTER_FRAME_ABSOLUTE; TRACE("hwnd=%p wayland_xy=%.2f,%.2f screen_xy=%d,%d\n", hwnd, wl_fixed_to_double(sx), wl_fixed_to_double(sy), screen.x, screen.y); - - NtUserSendHardwareInput(hwnd, 0, &input, 0); } static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, @@ -179,6 +186,7 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, } static void wayland_set_cursor(HWND hwnd, HCURSOR hcursor, BOOL use_hcursor); +static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer); static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *wl_surface, @@ -199,6 +207,7 @@ static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, pthread_mutex_lock(&pointer->mutex); pointer->focused_hwnd = hwnd; pointer->enter_serial = serial; + wayland_pointer_reset_frame(); pthread_mutex_unlock(&pointer->mutex); /* The cursor is undefined at every enter, so we set it again with @@ -209,6 +218,7 @@ static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer, * window first appears beneath the pointer and won't get a separate * motion event. */ pointer_handle_motion_internal(sx, sy); + pointer_handle_frame(data, pointer->wl_pointer); } static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer, @@ -279,6 +289,59 @@ static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) { + INPUT input = {0}; + HWND hwnd; + struct wayland_pointer *pointer = &process_wayland.pointer; + struct wayland_pointer_frame *frame = &pointer->frame; + + if (!(hwnd = wayland_pointer_get_focused_hwnd())) goto done; + + TRACE("hwnd=%p\n", hwnd); + + input.type = INPUT_MOUSE; + input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; + + if (frame->flags & WAYLAND_POINTER_FRAME_ABSOLUTE) + { + input.mi.dx = frame->x; + input.mi.dy = frame->y; + NtUserSendHardwareInput(hwnd, 0, &input, 0); + } + + input.mi.dwFlags = MOUSEEVENTF_MOVE; + + if (frame->flags & WAYLAND_POINTER_FRAME_RELATIVE) + { + input.mi.dx = round(frame->dx); + input.mi.dy = round(frame->dy); + frame->dx -= input.mi.dx; + frame->dy -= input.mi.dy; + if (input.mi.dx != 0 || input.mi.dy != 0) + NtUserSendHardwareInput(hwnd, 0, &input, 0); + } + + input.mi.dwFlags = MOUSEEVENTF_WHEEL; + input.mi.dx = input.mi.dy = 0; + + if (frame->flags & WAYLAND_POINTER_FRAME_WHEEL) + { + input.mi.mouseData = frame->scroll; + if (input.mi.mouseData) + NtUserSendHardwareInput(hwnd, 0, &input, 0); + } + + input.mi.dwFlags = MOUSEEVENTF_HWHEEL; + + if (frame->flags & WAYLAND_POINTER_FRAME_WHEEL_HORZ) + { + input.mi.mouseData = frame->horz_scroll; + if (input.mi.mouseData) + NtUserSendHardwareInput(hwnd, 0, &input, 0); + } + +done: + frame->flags = 0; + frame->scroll = frame->horz_scroll = 0; } static void pointer_handle_axis_source(void *data, struct wl_pointer *wl_pointer, @@ -294,29 +357,26 @@ static void pointer_handle_axis_stop(void *data, struct wl_pointer *wl_pointer, static void pointer_handle_axis_value120(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t value120) { - INPUT input = {0}; + struct wayland_pointer *pointer = &process_wayland.pointer; + struct wayland_pointer_frame *frame = &pointer->frame; HWND hwnd; if (!(hwnd = wayland_pointer_get_focused_hwnd())) return; - input.type = INPUT_MOUSE; - switch (axis) { case WL_POINTER_AXIS_VERTICAL_SCROLL: - input.mi.dwFlags = MOUSEEVENTF_WHEEL; - input.mi.mouseData = -value120; + frame->flags |= WAYLAND_POINTER_FRAME_WHEEL; + frame->scroll += -value120; break; case WL_POINTER_AXIS_HORIZONTAL_SCROLL: - input.mi.dwFlags = MOUSEEVENTF_HWHEEL; - input.mi.mouseData = value120; + frame->flags |= WAYLAND_POINTER_FRAME_WHEEL_HORZ; + frame->horz_scroll += value120; break; default: break; } TRACE("hwnd=%p axis=%u value120=%d\n", hwnd, axis, value120); - - NtUserSendHardwareInput(hwnd, 0, &input, 0); } static void pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_pointer, @@ -360,11 +420,11 @@ static void relative_pointer_v1_relative_motion(void *private, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_unaccel, wl_fixed_t dy_unaccel) { - INPUT input = {0}; HWND hwnd; struct wayland_win_data *data; double screen_x = 0.0, screen_y = 0.0; struct wayland_pointer *pointer = &process_wayland.pointer; + struct wayland_pointer_frame *frame = &pointer->frame; if (!(hwnd = wayland_pointer_get_focused_hwnd())) return; if (!(data = wayland_win_data_get(hwnd))) return; @@ -375,26 +435,12 @@ static void relative_pointer_v1_relative_motion(void *private, &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 = round(pointer->accum_x); - input.mi.dy = round(pointer->accum_y); - input.mi.dwFlags = MOUSEEVENTF_MOVE; - - pointer->accum_x -= input.mi.dx; - pointer->accum_y -= input.mi.dy; + frame->dx += screen_x; + frame->dy += screen_y; - 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); + frame->flags |= WAYLAND_POINTER_FRAME_RELATIVE; - NtUserSendHardwareInput(hwnd, 0, &input, 0); + TRACE("hwnd=%p screen=%.2f,%.2f\n", hwnd, screen_x, screen_y); } static const struct zwp_relative_pointer_v1_listener relative_pointer_v1_listener = @@ -981,7 +1027,7 @@ static void wayland_pointer_update_constraint(struct wl_surface *wl_surface, if (needs_relative && !pointer->zwp_relative_pointer_v1) { - pointer->accum_x = pointer->accum_y = 0; + pointer->frame.dx = pointer->frame.dy = 0.0; pointer->zwp_relative_pointer_v1 = zwp_relative_pointer_manager_v1_get_relative_pointer( process_wayland.zwp_relative_pointer_manager_v1, diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 5f4bd6a7cf6..8c414c0b2d1 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -102,6 +102,23 @@ struct wayland_cursor int hotspot_x, hotspot_y; }; +enum wayland_pointer_frame_flags +{ + WAYLAND_POINTER_FRAME_RELATIVE = (1 << 0), + WAYLAND_POINTER_FRAME_ABSOLUTE = (1 << 1), + WAYLAND_POINTER_FRAME_WHEEL = (1 << 2), + WAYLAND_POINTER_FRAME_WHEEL_HORZ = (1 << 3) +}; + +struct wayland_pointer_frame +{ + LONG x, y; + double dx, dy; + LONG scroll, horz_scroll; + + enum wayland_pointer_frame_flags flags; +}; + struct wayland_pointer { struct wl_pointer *wl_pointer; @@ -115,8 +132,7 @@ struct wayland_pointer uint32_t enter_serial; uint32_t button_serial; struct wayland_cursor cursor; - double accum_x; - double accum_y; + struct wayland_pointer_frame frame; pthread_mutex_t mutex; }; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11117
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_pointer.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 82fc15e5343..063bfc4ca94 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -298,6 +298,17 @@ static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) TRACE("hwnd=%p\n", hwnd); + pthread_mutex_lock(&pointer->mutex); + + /* cannot handle any new motion events when a warp is pending */ + if (pointer->pending_warp) + { + frame->flags &= ~(WAYLAND_POINTER_FRAME_ABSOLUTE + | WAYLAND_POINTER_FRAME_RELATIVE); + } + + pthread_mutex_unlock(&pointer->mutex); + input.type = INPUT_MOUSE; input.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11117
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_pointer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 063bfc4ca94..8544fc63b5b 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -1146,7 +1146,11 @@ BOOL WAYLAND_ClipCursor(const RECT *clip, BOOL reset) pointer->pending_warp = FALSE; } - if (wl_surface && hwnd == pointer->constraint_hwnd && pointer->zwp_locked_pointer_v1) + /* according to protocol spec, the position hints only do something + * when transitioning from locked to unlocked states */ + if (wl_surface && hwnd == pointer->constraint_hwnd && + pointer->zwp_locked_pointer_v1 && + (pointer->cursor.wl_surface || pointer->wp_cursor_shape_device_v1)) { zwp_locked_pointer_v1_set_cursor_position_hint( pointer->zwp_locked_pointer_v1, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11117
From: Rémi Bernon <rbernon@codeweavers.com> --- include/ntuser.h | 4 ++++ server/protocol.def | 3 +-- server/queue.c | 20 ++++++++++++-------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/include/ntuser.h b/include/ntuser.h index 2bbf77a4cf1..54d0d626d7b 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -1598,6 +1598,10 @@ struct hid_packet C_ASSERT(sizeof(struct hid_packet) == offsetof(struct hid_packet, data[0])); +#define SEND_HWMSG_INJECTED 1 +#define SEND_HWMSG_NO_RAW 2 +#define SEND_HWMSG_NO_MSG 4 + struct send_hardware_input_params { UINT flags; diff --git a/server/protocol.def b/server/protocol.def index e7d966613ac..ab028bcbf31 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2394,7 +2394,7 @@ enum message_type @REQ(send_hardware_message) user_handle_t win; /* window handle */ union hw_input input; /* input data */ - unsigned int flags; /* flags (see below) */ + unsigned int flags; /* flags (see ntuser.h) */ VARARG(report,bytes); /* HID report data */ @REPLY int wait; /* do we need to wait for a reply? */ @@ -2403,7 +2403,6 @@ enum message_type int new_x; /* new cursor position */ int new_y; @END -#define SEND_HWMSG_INJECTED 0x01 /* Get a message from the current queue */ diff --git a/server/queue.c b/server/queue.c index a04b53b70de..4182ee7bf86 100644 --- a/server/queue.c +++ b/server/queue.c @@ -2211,7 +2211,7 @@ static void dispatch_rawinput_message( struct desktop *desktop, struct rawinput_ /* queue a hardware message for a mouse event */ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, const union hw_input *input, - unsigned int origin, struct msg_queue *sender ) + unsigned int origin, struct msg_queue *sender, unsigned int send_flags ) { desktop_shm_t *desktop_shm = desktop->shared; struct hardware_msg_data *msg_data; @@ -2271,7 +2271,7 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons y = desktop_shm->cursor.y; } - if ((foreground = get_foreground_thread( desktop, win ))) + if (!(send_flags & SEND_HWMSG_NO_RAW) && (foreground = get_foreground_thread( desktop, win ))) { memset( &raw_msg, 0, sizeof(raw_msg) ); raw_msg.foreground = foreground; @@ -2286,6 +2286,8 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons release_object( foreground ); } + if (send_flags & SEND_HWMSG_NO_MSG) return 0; + for (i = 0; i < ARRAY_SIZE( messages ); i++) { if (!messages[i]) continue; @@ -2316,14 +2318,14 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons } static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const union hw_input *input, - unsigned int origin, struct msg_queue *sender, int repeat ); + unsigned int origin, struct msg_queue *sender, int repeat, unsigned int send_flags); static void key_repeat_timeout( void *private ) { struct desktop *desktop = private; desktop->key_repeat.timeout = NULL; - queue_keyboard_message( desktop, desktop->key_repeat.win, &desktop->key_repeat.input, IMO_HARDWARE, NULL, 1 ); + queue_keyboard_message( desktop, desktop->key_repeat.win, &desktop->key_repeat.input, IMO_HARDWARE, NULL, 1, 0 ); } static void stop_key_repeat( struct desktop *desktop ) @@ -2336,7 +2338,7 @@ static void stop_key_repeat( struct desktop *desktop ) /* queue a hardware message for a keyboard event */ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, const union hw_input *input, - unsigned int origin, struct msg_queue *sender, int repeat ) + unsigned int origin, struct msg_queue *sender, int repeat, unsigned int send_flags ) { desktop_shm_t *desktop_shm = desktop->shared; struct hw_msg_source source = { IMDT_KEYBOARD, origin }; @@ -2459,7 +2461,7 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c } } - if (!unicode && (foreground = get_foreground_thread( desktop, win ))) + if (!(send_flags & SEND_HWMSG_NO_RAW) && ((!unicode && (foreground = get_foreground_thread( desktop, win ))))) { struct rawinput_message raw_msg = {0}; raw_msg.foreground = foreground; @@ -2474,6 +2476,8 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c release_object( foreground ); } + if (send_flags & SEND_HWMSG_NO_MSG) return 0; + if (!(msg = alloc_hardware_message( input->kbd.info, source, time, 0 ))) return 0; msg_data = msg->data; @@ -3258,10 +3262,10 @@ DECL_HANDLER(send_hardware_message) switch (req->input.type) { case INPUT_MOUSE: - wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender ); + wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender, req->flags ); break; case INPUT_KEYBOARD: - wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender, 0 ); + wait = queue_keyboard_message( desktop, req->win, &req->input, origin, sender, 0, req->flags ); break; case INPUT_HARDWARE: queue_custom_hardware_message( desktop, req->win, origin, &req->input ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11117
From: Etaash Mathamsetty <etaash.mathamsetty@gmail.com> --- dlls/winewayland.drv/wayland_pointer.c | 61 ++++++++++++-------------- dlls/winewayland.drv/waylanddrv.h | 2 + 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index 8544fc63b5b..78d793836af 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -126,6 +126,7 @@ static void wayland_pointer_reset_frame(void) struct wayland_pointer_frame *frame = &process_wayland.pointer.frame; frame->dx = frame->dy = 0.0; + frame->dx_raw = frame->dy_raw = 0.0; frame->horz_scroll = frame->scroll = 0; frame->flags = 0; } @@ -180,7 +181,7 @@ static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, struct wayland_pointer *pointer = &process_wayland.pointer; /* Ignore absolute motion events if in relative mode. */ - if (pointer->zwp_relative_pointer_v1) return; + if (pointer->relative_mode) return; pointer_handle_motion_internal(sx, sy); } @@ -316,7 +317,7 @@ static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) { input.mi.dx = frame->x; input.mi.dy = frame->y; - NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, SEND_HWMSG_NO_RAW, &input, 0); } input.mi.dwFlags = MOUSEEVENTF_MOVE; @@ -328,7 +329,14 @@ static void pointer_handle_frame(void *data, struct wl_pointer *wl_pointer) frame->dx -= input.mi.dx; frame->dy -= input.mi.dy; if (input.mi.dx != 0 || input.mi.dy != 0) - NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, SEND_HWMSG_NO_RAW, &input, 0); + + input.mi.dx = round(frame->dx_raw); + input.mi.dy = round(frame->dy_raw); + frame->dx_raw -= input.mi.dx; + frame->dy_raw -= input.mi.dy; + if (input.mi.dx != 0 || input.mi.dy != 0) + NtUserSendHardwareInput(hwnd, SEND_HWMSG_NO_MSG, &input, 0); } input.mi.dwFlags = MOUSEEVENTF_WHEEL; @@ -434,6 +442,8 @@ static void relative_pointer_v1_relative_motion(void *private, HWND hwnd; struct wayland_win_data *data; double screen_x = 0.0, screen_y = 0.0; + double raw_x = wl_fixed_to_double(dx_unaccel); + double raw_y = wl_fixed_to_double(dy_unaccel); struct wayland_pointer *pointer = &process_wayland.pointer; struct wayland_pointer_frame *frame = &pointer->frame; @@ -448,10 +458,12 @@ static void relative_pointer_v1_relative_motion(void *private, frame->dx += screen_x; frame->dy += screen_y; + frame->dx_raw += raw_x; + frame->dy_raw += raw_y; frame->flags |= WAYLAND_POINTER_FRAME_RELATIVE; - TRACE("hwnd=%p screen=%.2f,%.2f\n", hwnd, screen_x, screen_y); + TRACE("hwnd=%p screen=%.2f,%.2f raw=%.2f,%.2f\n", hwnd, screen_x, screen_y, raw_x, raw_y); } static const struct zwp_relative_pointer_v1_listener relative_pointer_v1_listener = @@ -467,6 +479,15 @@ void wayland_pointer_init(struct wl_pointer *wl_pointer) pointer->wl_pointer = wl_pointer; pointer->focused_hwnd = NULL; pointer->enter_serial = 0; + if (process_wayland.zwp_relative_pointer_manager_v1) + { + pointer->zwp_relative_pointer_v1 = + zwp_relative_pointer_manager_v1_get_relative_pointer( + 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); + } pthread_mutex_unlock(&pointer->mutex); wl_pointer_add_listener(pointer->wl_pointer, &pointer_listener, NULL); } @@ -1026,33 +1047,9 @@ static void wayland_pointer_update_constraint(struct wl_surface *wl_surface, } } - if (!process_wayland.zwp_relative_pointer_manager_v1) - { - if (!once++) - ERR("zwp_relative_pointer_manager_v1 isn't supported, skipping relative motion\n"); - return; - } - - needs_relative = !is_visible && pointer->constraint_hwnd && - pointer->constraint_hwnd == pointer->focused_hwnd; - - if (needs_relative && !pointer->zwp_relative_pointer_v1) - { - pointer->frame.dx = pointer->frame.dy = 0.0; - pointer->zwp_relative_pointer_v1 = - zwp_relative_pointer_manager_v1_get_relative_pointer( - 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); - TRACE("Enabling relative motion\n"); - } - else if (!needs_relative && pointer->zwp_relative_pointer_v1) - { - zwp_relative_pointer_v1_destroy(pointer->zwp_relative_pointer_v1); - pointer->zwp_relative_pointer_v1 = NULL; - TRACE("Disabling relative motion\n"); - } + pointer->relative_mode = !is_visible && pointer->constraint_hwnd && + pointer->constraint_hwnd == pointer->focused_hwnd && + pointer->zwp_relative_pointer_v1; } void wayland_pointer_clear_constraint(void) @@ -1078,7 +1075,7 @@ BOOL WAYLAND_SetCursorPos(INT x, INT y) struct wayland_pointer *pointer = &process_wayland.pointer; pthread_mutex_lock(&pointer->mutex); - if (pointer->zwp_relative_pointer_v1) + if (pointer->relative_mode) { pthread_mutex_unlock(&pointer->mutex); return FALSE; diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 8c414c0b2d1..0530b25cc58 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -114,6 +114,7 @@ struct wayland_pointer_frame { LONG x, y; double dx, dy; + double dx_raw, dy_raw; LONG scroll, horz_scroll; enum wayland_pointer_frame_flags flags; @@ -129,6 +130,7 @@ struct wayland_pointer HWND focused_hwnd; HWND constraint_hwnd; BOOL pending_warp; + BOOL relative_mode; uint32_t enter_serial; uint32_t button_serial; struct wayland_cursor cursor; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11117
participants (3)
-
Etaash Mathamsetty -
Etaash Mathamsetty (@etaash.mathamsetty) -
Rémi Bernon