From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/wayland_surface.c | 17 ++++++++++++++++- dlls/winewayland.drv/waylanddrv.h | 1 + dlls/winewayland.drv/window.c | 20 +++++++++++++++++--- 3 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 27d1fde8c12..1cf5dd3f8ce 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -513,7 +513,11 @@ void wayland_surface_reconfigure_client(struct wayland_surface *surface, struct
TRACE("hwnd=%p subsurface=%d,%d+%dx%d\n", surface->hwnd, x, y, width, height);
- wl_subsurface_set_position(client->wl_subsurface, x, y); + if (client->wl_subsurface) + { + wl_subsurface_set_position(client->wl_subsurface, x, y); + wl_subsurface_place_above(client->wl_subsurface, surface->wl_surface); + }
if (width != 0 && height != 0) wp_viewport_set_destination(client->wp_viewport, width, height); @@ -815,6 +819,8 @@ err:
void wayland_client_surface_attach(struct wayland_client_surface *client, struct wayland_surface *surface) { + wayland_client_surface_detach(client); + client->wl_subsurface = wl_subcompositor_get_subsurface(process_wayland.wl_subcompositor, client->wl_surface, @@ -832,6 +838,15 @@ void wayland_client_surface_attach(struct wayland_client_surface *client, struct wl_surface_commit(surface->wl_surface); }
+void wayland_client_surface_detach(struct wayland_client_surface *client) +{ + if (client->wl_subsurface) + { + wl_subsurface_destroy(client->wl_subsurface); + client->wl_subsurface = NULL; + } +} + static void dummy_buffer_release(void *data, struct wl_buffer *buffer) { struct wayland_shm_buffer *shm_buffer = data; diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index ecefeeb77af..9de42758aa1 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -255,6 +255,7 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface, struct wayland_client_surface *wayland_client_surface_create(HWND hwnd); BOOL wayland_client_surface_release(struct wayland_client_surface *client); void wayland_client_surface_attach(struct wayland_client_surface *client, struct wayland_surface *surface); +void wayland_client_surface_detach(struct wayland_client_surface *client); void wayland_surface_ensure_contents(struct wayland_surface *surface, struct wayland_client_surface *client); void wayland_surface_set_title(struct wayland_surface *surface, LPCWSTR title);
diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index a839c14d537..cf256657d2b 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -195,6 +195,7 @@ static void reapply_cursor_clipping(void)
static void wayland_win_data_update_wayland_surface(struct wayland_win_data *data) { + struct wayland_client_surface *client = data->client_surface; struct wayland_surface *surface = data->wayland_surface; HWND parent = NtUserGetAncestor(data->hwnd, GA_PARENT); BOOL visible, xdg_visible; @@ -205,7 +206,11 @@ static void wayland_win_data_update_wayland_surface(struct wayland_win_data *dat /* We don't want wayland surfaces for child windows. */ if (parent != NtUserGetDesktopWindow() && parent != 0) { - if (surface) wayland_surface_destroy(surface); + if (surface) + { + if (client) wayland_client_surface_attach(client, surface); + wayland_surface_destroy(surface); + } surface = NULL; goto out; } @@ -219,13 +224,18 @@ static void wayland_win_data_update_wayland_surface(struct wayland_win_data *dat if (visible != xdg_visible) { /* If we have a pre-existing surface ensure it has no role. */ - if (data->wayland_surface) wayland_surface_clear_role(surface); + if (data->wayland_surface) + { + if (client) wayland_client_surface_detach(client); + wayland_surface_clear_role(surface); + } /* 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. */ if (visible) { wayland_surface_make_toplevel(surface); + if (client) wayland_client_surface_attach(client, surface); if (surface->xdg_toplevel) { if (!NtUserInternalGetWindowText(data->hwnd, text, ARRAY_SIZE(text))) @@ -712,9 +722,13 @@ struct wayland_client_surface *get_client_surface(HWND hwnd, RECT *client_rect) } if (!data) return client;
+ if (surface && NtUserIsWindowVisible(hwnd)) + wayland_client_surface_attach(client, surface); + else + wayland_client_surface_detach(client); + if (!data->client_surface) { - if (surface) wayland_client_surface_attach(client, surface); InterlockedIncrement(&client->ref); data->client_surface = client; }