Set an empty Wayland input region for windows that as marked as WS_EX_TRANSPARENT | WS_EX_LAYERED in order to match the Windows behavior.
Setting an empty input region prevents the compositor from giving the pointer focus to the corresponding surface in the first place, and improves consistency between the Win32 mouse and Wayland pointer focus states.
From: Alexandros Frantzis alexandros.frantzis@collabora.com
Set an empty Wayland input region for windows that as marked as WS_EX_TRANSPARENT | WS_EX_LAYERED in order to match the Windows behavior.
Setting an empty input region prevents the compositor from giving the pointer focus to the corresponding surface in the first place, and improves consistency between the Win32 mouse and Wayland pointer focus states.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58650 --- dlls/winewayland.drv/window.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 3b94112dc6d..2f508980dc5 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -193,12 +193,13 @@ static BOOL wayland_win_data_create_wayland_surface(struct wayland_win_data *dat struct wayland_surface *surface; enum wayland_surface_role role; BOOL visible; + DWORD exstyle = NtUserGetWindowLongW(data->hwnd, GWL_EXSTYLE); + struct wl_region *input_region;
TRACE("hwnd=%p\n", data->hwnd);
visible = ((NtUserGetWindowLongW(data->hwnd, GWL_STYLE) & WS_VISIBLE) == WS_VISIBLE) && - (!(NtUserGetWindowLongW(data->hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) || - data->layered_attribs_set); + (!(exstyle & WS_EX_LAYERED) || data->layered_attribs_set);
if (!visible) role = WAYLAND_SURFACE_ROLE_NONE; else if (toplevel_surface) role = WAYLAND_SURFACE_ROLE_SUBSURFACE; @@ -214,6 +215,14 @@ static BOOL wayland_win_data_create_wayland_surface(struct wayland_win_data *dat
if (!(surface = data->wayland_surface) && !(surface = wayland_surface_create(data->hwnd))) return FALSE;
+ /* Pass through mouse events for layered, transparent windows, to match + * Windows behavior. */ + input_region = (exstyle & (WS_EX_TRANSPARENT | WS_EX_LAYERED)) ? + wl_compositor_create_region(process_wayland.wl_compositor) : + NULL; + wl_surface_set_input_region(surface->wl_surface, input_region); + if (input_region) wl_region_destroy(input_region); + /* If the window is a visible toplevel make it a wayland * xdg_toplevel. Otherwise keep it role-less to avoid polluting the * compositor with empty xdg_toplevels. */
Note that the fix from https://gitlab.winehq.org/wine/wine/-/merge_requests/9198 is needed to test this branch, as the mouse cursor is broken on winewayland without it.
Are you sure that layered windows aren't supposed to receive pointer input?