From: Alexandros Frantzis alexandros.frantzis@collabora.com
Since the positions of win32 windows and their corresponding Wayland surfaces are not synchronized, there are cases where parts of a window are outside the vscreen boundaries, and thus inaccessible to input events, but still visible and accessible from a user (i.e., Wayland compositor) standpoint. Try to remedy this issue by instructing the Wine server to not clip the Wayland mouse event coordinates to vscreen boundaries. --- dlls/winewayland.drv/wayland_pointer.c | 9 +++++---- include/wine/server_protocol.h | 3 ++- server/protocol.def | 1 + server/queue.c | 17 ++++++++++++----- server/user.h | 1 + 5 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index beb9cc06702..f8b995b73a9 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -31,6 +31,7 @@
#include "waylanddrv.h" #include "wine/debug.h" +#include "wine/server_protocol.h"
WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
@@ -89,7 +90,7 @@ static void pointer_handle_motion_internal(wl_fixed_t sx, wl_fixed_t sy) hwnd, wl_fixed_to_double(sx), wl_fixed_to_double(sy), screen.x, screen.y);
- NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, SEND_HWMSG_NO_VSCREEN_CLIP, &input, 0); }
static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer, @@ -194,7 +195,7 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
TRACE("hwnd=%p button=%#x state=%u\n", hwnd, button, state);
- NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, SEND_HWMSG_NO_VSCREEN_CLIP, &input, 0); }
static void pointer_handle_axis(void *data, struct wl_pointer *wl_pointer, @@ -241,7 +242,7 @@ static void pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_point
TRACE("hwnd=%p axis=%u discrete=%d\n", hwnd, axis, discrete);
- NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, SEND_HWMSG_NO_VSCREEN_CLIP, &input, 0); }
static const struct wl_pointer_listener pointer_listener = @@ -310,7 +311,7 @@ static void relative_pointer_v1_relative_motion(void *private, hwnd, wl_fixed_to_double(dx), wl_fixed_to_double(dy), input.mi.dx, input.mi.dy);
- NtUserSendHardwareInput(hwnd, 0, &input, 0); + NtUserSendHardwareInput(hwnd, SEND_HWMSG_NO_VSCREEN_CLIP, &input, 0); }
static const struct zwp_relative_pointer_v1_listener relative_pointer_v1_listener = diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 3cdc9375e2d..708355e212a 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -3047,6 +3047,7 @@ struct send_hardware_message_reply char __pad_28[4]; }; #define SEND_HWMSG_INJECTED 0x01 +#define SEND_HWMSG_NO_VSCREEN_CLIP 0x02
@@ -6798,6 +6799,6 @@ union generic_reply struct set_keyboard_repeat_reply set_keyboard_repeat_reply; };
-#define SERVER_PROTOCOL_VERSION 863 +#define SERVER_PROTOCOL_VERSION 864
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index 63bb0111473..b500b5b838c 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2315,6 +2315,7 @@ enum message_type int new_y; @END #define SEND_HWMSG_INJECTED 0x01 +#define SEND_HWMSG_NO_VSCREEN_CLIP 0x02
/* Get a message from the current queue */ diff --git a/server/queue.c b/server/queue.c index b4b6069f927..9271840b165 100644 --- a/server/queue.c +++ b/server/queue.c @@ -534,8 +534,11 @@ static int update_desktop_cursor_pos( struct desktop *desktop, user_handle_t win int updated; unsigned int time = get_tick_count();
- x = max( min( x, desktop_shm->cursor.clip.right - 1 ), desktop_shm->cursor.clip.left ); - y = max( min( y, desktop_shm->cursor.clip.bottom - 1 ), desktop_shm->cursor.clip.top ); + if (!(desktop->cursor_flags & SEND_HWMSG_NO_VSCREEN_CLIP) || is_cursor_clipped( desktop )) + { + x = max( min( x, desktop_shm->cursor.clip.right - 1 ), desktop_shm->cursor.clip.left ); + y = max( min( y, desktop_shm->cursor.clip.bottom - 1 ), desktop_shm->cursor.clip.top ); + }
SHARED_WRITE_BEGIN( desktop_shm, desktop_shm_t ) { @@ -635,9 +638,12 @@ void set_clip_rectangle( struct desktop *desktop, const struct rectangle *rect, desktop->clip_flags = flags;
/* warp the mouse to be inside the clip rect */ - x = max( min( desktop_shm->cursor.x, new_rect.right - 1 ), new_rect.left ); - y = max( min( desktop_shm->cursor.y, new_rect.bottom - 1 ), new_rect.top ); - if (x != desktop_shm->cursor.x || y != desktop_shm->cursor.y) set_cursor_pos( desktop, x, y ); + if (!(desktop->cursor_flags & SEND_HWMSG_NO_VSCREEN_CLIP) || is_cursor_clipped( desktop )) + { + x = max( min( desktop_shm->cursor.x, new_rect.right - 1 ), new_rect.left ); + y = max( min( desktop_shm->cursor.y, new_rect.bottom - 1 ), new_rect.top ); + if (x != desktop_shm->cursor.x || y != desktop_shm->cursor.y) set_cursor_pos( desktop, x, y ); + }
/* request clip cursor rectangle reset to the desktop thread */ if (reset) post_desktop_message( desktop, WM_WINE_CLIPCURSOR, flags, FALSE ); @@ -3296,6 +3302,7 @@ DECL_HANDLER(send_hardware_message) switch (req->input.type) { case INPUT_MOUSE: + desktop->cursor_flags = req->flags; wait = queue_mouse_message( desktop, req->win, &req->input, origin, sender ); break; case INPUT_KEYBOARD: diff --git a/server/user.h b/server/user.h index ce463b9395d..dbee4b56a4a 100644 --- a/server/user.h +++ b/server/user.h @@ -94,6 +94,7 @@ struct desktop struct key_repeat key_repeat; /* key auto-repeat */ unsigned int clip_flags; /* last cursor clip flags */ user_handle_t cursor_win; /* window that contains the cursor */ + unsigned int cursor_flags; /* last cursor flags */ const desktop_shm_t *shared; /* desktop session shared memory */ };