xdg-shell: avoid leaving dangling pointers on resource creation failure

Currently if weston_desktop_surface_add_resource() fails to create a
wl_resource, it disconnects the client and destroys the desktop surface
that we pass.

It is odd to do that, callers should be responsible for destroying the
desktop surface when it is reasonable to do so. This is dangerous and
can leave dangling pointers.

Besides that, in many cases callers should not even destroy the desktop
surface, as they are not the owners of it. When we are giving the role
of toplevel/popup to a xdg_surface and we fail to do so, client gets
disconnected and the base desktop surface will get destroyed by the
destructor of the xdg_surface resource.

This commit fixes these issues, bringing a more consistent behavior.

Signed-off-by: Leandro Ribeiro <leandro.ribeiro@collabora.com>
This commit is contained in:
Leandro Ribeiro 2026-02-02 13:34:12 -03:00
parent a3f22240c2
commit 385647d357
3 changed files with 10 additions and 3 deletions

View file

@ -330,7 +330,6 @@ weston_desktop_surface_add_resource(struct weston_desktop_surface *surface,
id);
if (resource == NULL) {
wl_client_post_no_memory(wl_client);
weston_desktop_surface_destroy(surface);
return NULL;
}
if (destroy == NULL)

View file

@ -1492,13 +1492,18 @@ weston_desktop_xdg_shell_protocol_get_xdg_surface(struct wl_client *wl_client,
&zxdg_surface_v6_interface,
&weston_desktop_xdg_surface_implementation,
id, weston_desktop_xdg_surface_resource_destroy);
if (surface->resource == NULL)
if (surface->resource == NULL) {
weston_desktop_surface_destroy(surface->desktop_surface);
free(surface);
return;
}
if (weston_surface_has_content(wsurface)) {
wl_resource_post_error(surface->resource,
ZXDG_SURFACE_V6_ERROR_UNCONFIGURED_BUFFER,
"xdg_surface must not have a buffer at creation");
weston_desktop_surface_destroy(surface->desktop_surface);
free(surface);
return;
}
}

View file

@ -2087,8 +2087,11 @@ weston_desktop_xdg_shell_protocol_get_xdg_surface(struct wl_client *wl_client,
&xdg_surface_interface,
&weston_desktop_xdg_surface_implementation,
id, weston_desktop_xdg_surface_resource_destroy);
if (surface->resource == NULL)
if (surface->resource == NULL) {
weston_desktop_surface_destroy(surface->desktop_surface);
free(surface);
return;
}
}
static void