surface: fix destroyed subsurfaces handling

wlr_subsurface_from_wlr_surface can return NULL if the wl_surface is still
alive and if the wl_subsurface has been destroyed. Make sure we check for NULL.

Fixes https://github.com/swaywm/sway/issues/3195
master
emersion 6 years ago
parent eaa852ed77
commit a5b8ea90d2
No known key found for this signature in database
GPG Key ID: 0FDE7BE0E88F5E48

@ -43,6 +43,10 @@ struct wlr_compositor *wlr_compositor_create(struct wl_display *display,
bool wlr_surface_is_subsurface(struct wlr_surface *surface); bool wlr_surface_is_subsurface(struct wlr_surface *surface);
/**
* Get a subsurface from a surface. Can return NULL if the subsurface has been
* destroyed.
*/
struct wlr_subsurface *wlr_subsurface_from_wlr_surface( struct wlr_subsurface *wlr_subsurface_from_wlr_surface(
struct wlr_surface *surface); struct wlr_surface *surface);

@ -376,7 +376,7 @@ static void surface_commit_pending(struct wlr_surface *surface) {
} }
static bool subsurface_is_synchronized(struct wlr_subsurface *subsurface) { static bool subsurface_is_synchronized(struct wlr_subsurface *subsurface) {
while (1) { while (subsurface != NULL) {
if (subsurface->synchronized) { if (subsurface->synchronized) {
return true; return true;
} }
@ -436,15 +436,14 @@ static void surface_commit(struct wl_client *client,
struct wl_resource *resource) { struct wl_resource *resource) {
struct wlr_surface *surface = wlr_surface_from_resource(resource); struct wlr_surface *surface = wlr_surface_from_resource(resource);
if (wlr_surface_is_subsurface(surface)) { struct wlr_subsurface *subsurface = wlr_surface_is_subsurface(surface) ?
struct wlr_subsurface *subsurface = wlr_subsurface_from_wlr_surface(surface) : NULL;
wlr_subsurface_from_wlr_surface(surface); if (subsurface != NULL) {
subsurface_commit(subsurface); subsurface_commit(subsurface);
} else { } else {
surface_commit_pending(surface); surface_commit_pending(surface);
} }
struct wlr_subsurface *subsurface;
wl_list_for_each(subsurface, &surface->subsurfaces, parent_link) { wl_list_for_each(subsurface, &surface->subsurfaces, parent_link) {
subsurface_parent_commit(subsurface, false); subsurface_parent_commit(subsurface, false);
} }
@ -904,6 +903,9 @@ struct wlr_surface *wlr_surface_get_root_surface(struct wlr_surface *surface) {
while (wlr_surface_is_subsurface(surface)) { while (wlr_surface_is_subsurface(surface)) {
struct wlr_subsurface *subsurface = struct wlr_subsurface *subsurface =
wlr_subsurface_from_wlr_surface(surface); wlr_subsurface_from_wlr_surface(surface);
if (subsurface == NULL) {
break;
}
surface = subsurface->parent; surface = subsurface->parent;
} }
return surface; return surface;

Loading…
Cancel
Save