From da34ef8dd4c833371f2592de0f9854ef9c34774d Mon Sep 17 00:00:00 2001 From: numzero Date: Thu, 5 Aug 2021 00:35:17 +0300 Subject: [PATCH] Destroy Sway subsurfaces when destroying Sway layer_surface Otherwise destroying wlr_layer_surface could destroy sway_layer_surface before destroying its subsurfaces that would try to access the sway_layer_surface regardless, possibly crashing Sway. --- include/sway/layers.h | 5 +++++ sway/desktop/layer_shell.c | 26 +++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/include/sway/layers.h b/include/sway/layers.h index 82ac53680..06f209d5b 100644 --- a/include/sway/layers.h +++ b/include/sway/layers.h @@ -21,6 +21,10 @@ struct sway_layer_surface { struct wl_listener new_popup; struct wl_listener new_subsurface; + struct { + struct wl_signal destroy; + } events; + struct wlr_box geo; enum zwlr_layer_shell_v1_layer layer; }; @@ -47,6 +51,7 @@ struct sway_layer_subsurface { struct wl_listener unmap; struct wl_listener destroy; struct wl_listener commit; + struct wl_listener surface_destroy; }; struct sway_output; diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index cadc702ab..13ddb8085 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c @@ -352,6 +352,7 @@ static void handle_destroy(struct wl_listener *listener, void *data) { if (sway_layer->layer_surface->mapped) { unmap(sway_layer); } + wl_signal_emit(&sway_layer->events.destroy, sway_layer); wl_list_remove(&sway_layer->link); wl_list_remove(&sway_layer->destroy.link); wl_list_remove(&sway_layer->map.link); @@ -420,18 +421,29 @@ static void subsurface_handle_commit(struct wl_listener *listener, void *data) { subsurface_damage(subsurface, false); } -static void subsurface_handle_destroy(struct wl_listener *listener, - void *data) { - struct sway_layer_subsurface *subsurface = - wl_container_of(listener, subsurface, destroy); - +static void subsurface_destroy(struct sway_layer_subsurface *subsurface) { wl_list_remove(&subsurface->map.link); wl_list_remove(&subsurface->unmap.link); wl_list_remove(&subsurface->destroy.link); wl_list_remove(&subsurface->commit.link); + wl_list_remove(&subsurface->surface_destroy.link); free(subsurface); } +static void subsurface_handle_destroy(struct wl_listener *listener, + void *data) { + struct sway_layer_subsurface *subsurface = + wl_container_of(listener, subsurface, destroy); + subsurface_destroy(subsurface); +} + +static void subsurface_handle_surface_destroy(struct wl_listener *listener, + void *data) { + struct sway_layer_subsurface *subsurface = + wl_container_of(listener, subsurface, surface_destroy); + subsurface_destroy(subsurface); +} + static struct sway_layer_subsurface *create_subsurface( struct wlr_subsurface *wlr_subsurface, struct sway_layer_surface *layer_surface) { @@ -452,6 +464,8 @@ static struct sway_layer_subsurface *create_subsurface( wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy); subsurface->commit.notify = subsurface_handle_commit; wl_signal_add(&wlr_subsurface->surface->events.commit, &subsurface->commit); + subsurface->surface_destroy.notify = subsurface_handle_surface_destroy; + wl_signal_add(&layer_surface->events.destroy, &subsurface->surface_destroy); return subsurface; } @@ -635,6 +649,8 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { return; } + wl_signal_init(&sway_layer->events.destroy); + sway_layer->surface_commit.notify = handle_surface_commit; wl_signal_add(&layer_surface->surface->events.commit, &sway_layer->surface_commit);