libweston/desktop: Don't destroy the xdg_surface

Upon xdg_toplevel::destroy we seem to be calling xdg_surface::destroy
destroy handler. Protocol states that we should umap the surface with
client having the posibility to getting another toplevel role for the
same xdg_surface and re-map the window.

This also adds a guard for an unlikely invalid resource.

Fixes: #774

Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
(cherry picked from commit 8b5bb588df)
This commit is contained in:
Marius Vlad 2024-10-18 10:44:17 +03:00
parent 61f2248de2
commit 26e03f3891
2 changed files with 51 additions and 17 deletions

View file

@ -781,8 +781,16 @@ weston_desktop_xdg_toplevel_resource_destroy(struct wl_resource *resource)
struct weston_desktop_surface *dsurface =
wl_resource_get_user_data(resource);
if (dsurface != NULL)
weston_desktop_surface_resource_destroy(resource);
if (dsurface) {
struct weston_desktop_xdg_toplevel *toplevel =
weston_desktop_surface_get_implementation_data(dsurface);
struct weston_surface *wsurface =
weston_desktop_surface_get_surface(dsurface);
weston_surface_unmap(wsurface);
wl_list_remove(wl_resource_get_link(resource));
toplevel->resource = NULL;
}
}
static const struct zxdg_toplevel_v6_interface weston_desktop_xdg_toplevel_implementation = {
@ -1072,12 +1080,20 @@ weston_desktop_xdg_surface_protocol_get_toplevel(struct wl_client *wl_client,
struct wl_resource *resource,
uint32_t id)
{
struct weston_desktop_surface *dsurface =
wl_resource_get_user_data(resource);
struct weston_surface *wsurface =
weston_desktop_surface_get_surface(dsurface);
struct weston_desktop_xdg_toplevel *toplevel =
weston_desktop_surface_get_implementation_data(dsurface);
struct weston_desktop_surface *dsurface = NULL;
struct weston_surface *wsurface = NULL;
struct weston_desktop_xdg_toplevel *toplevel = NULL;
dsurface = wl_resource_get_user_data(resource);
if (!dsurface) {
wl_resource_post_error(resource,
ZXDG_SURFACE_V6_ERROR_NOT_CONSTRUCTED,
"xdg surface destroyed");
return;
}
wsurface = weston_desktop_surface_get_surface(dsurface);
toplevel = weston_desktop_surface_get_implementation_data(dsurface);
if (weston_surface_set_role(wsurface, weston_desktop_xdg_toplevel_role,
resource, ZXDG_SHELL_V6_ERROR_ROLE) < 0)

View file

@ -887,8 +887,17 @@ weston_desktop_xdg_toplevel_resource_destroy(struct wl_resource *resource)
struct weston_desktop_surface *dsurface =
wl_resource_get_user_data(resource);
if (dsurface != NULL)
weston_desktop_surface_resource_destroy(resource);
if (dsurface) {
struct weston_desktop_xdg_toplevel *toplevel =
weston_desktop_surface_get_implementation_data(dsurface);
struct weston_surface *wsurface =
weston_desktop_surface_get_surface(dsurface);
weston_surface_unmap(wsurface);
wl_list_remove(wl_resource_get_link(resource));
toplevel->resource = NULL;
}
}
static const struct xdg_toplevel_interface weston_desktop_xdg_toplevel_implementation = {
@ -1246,13 +1255,22 @@ weston_desktop_xdg_surface_protocol_get_toplevel(struct wl_client *wl_client,
struct wl_resource *resource,
uint32_t id)
{
struct weston_desktop_surface *dsurface =
wl_resource_get_user_data(resource);
struct weston_surface *wsurface =
weston_desktop_surface_get_surface(dsurface);
struct weston_desktop_xdg_toplevel *toplevel =
weston_desktop_surface_get_implementation_data(dsurface);
struct weston_desktop *desktop = toplevel->base.desktop;
struct weston_desktop_surface *dsurface = NULL;
struct weston_surface *wsurface = NULL;
struct weston_desktop_xdg_toplevel *toplevel = NULL;
struct weston_desktop *desktop = NULL;
dsurface = wl_resource_get_user_data(resource);
if (!dsurface) {
wl_resource_post_error(resource,
XDG_SURFACE_ERROR_DEFUNCT_ROLE_OBJECT,
"xdg surface destroyed");
return;
}
wsurface = weston_desktop_surface_get_surface(dsurface);
toplevel = weston_desktop_surface_get_implementation_data(dsurface);
desktop = toplevel->base.desktop;
if (weston_surface_set_role(wsurface, weston_desktop_xdg_toplevel_role,
resource, XDG_WM_BASE_ERROR_ROLE) < 0)