layers: arrange layers on destroy

...rather than unmap because that is the approach of sway and it also
avoids wshowkeys crashing.

Fixes: #1153
This commit is contained in:
Johan Malm 2023-10-10 21:51:58 +01:00 committed by Johan Malm
parent ca94abbef1
commit 7bf08af210
3 changed files with 23 additions and 4 deletions

View file

@ -11,6 +11,8 @@ struct seat;
struct lab_layer_surface {
struct wlr_scene_layer_surface_v1 *scene_layer_surface;
struct server *server;
struct output *output;
struct wlr_scene_tree *tree;
bool mapped;

View file

@ -45,6 +45,13 @@ arrange_one_layer(const struct wlr_box *full_area, struct wlr_box *usable_area,
{
struct wlr_scene_node *node;
wl_list_for_each(node, &tree->children, link) {
/*
* Could be null during destruction when called from
* handle_node_destroy()
*/
if (!node->data) {
continue;
}
struct lab_layer_surface *surface = node_layer_surface_from_node(node);
struct wlr_scene_layer_surface_v1 *scene = surface->scene_layer_surface;
if (!scene->layer_surface->initialized) {
@ -119,6 +126,7 @@ handle_output_destroy(struct wl_listener *listener, void *data)
struct lab_layer_surface *layer =
wl_container_of(listener, layer, output_destroy);
layer->scene_layer_surface->layer_surface->output = NULL;
layer->output = NULL;
wlr_layer_surface_v1_destroy(layer->scene_layer_surface->layer_surface);
}
@ -312,6 +320,16 @@ handle_node_destroy(struct wl_listener *listener, void *data)
* focus to.
*/
/*
* Nullify node descriptor early to avoid functions such as
* arrange_one_layer() trying to dereference it.
*/
layer->tree->node.data = NULL;
if (layer->output) {
output_update_usable_area(layer->output);
}
wl_list_remove(&layer->map.link);
wl_list_remove(&layer->unmap.link);
wl_list_remove(&layer->surface_commit.link);
@ -327,9 +345,6 @@ handle_unmap(struct wl_listener *listener, void *data)
struct lab_layer_surface *layer = wl_container_of(listener, layer, unmap);
struct wlr_layer_surface_v1 *layer_surface =
layer->scene_layer_surface->layer_surface;
if (layer_surface->output) {
output_update_usable_area(layer_surface->output->data);
}
struct seat *seat = &layer->server->seat;
if (seat->focused_layer == layer_surface) {
try_to_focus_next_layer_or_toplevel(layer->server);
@ -552,6 +567,7 @@ handle_new_layer_surface(struct wl_listener *listener, void *data)
struct lab_layer_surface *surface = znew(*surface);
struct output *output = layer_surface->output->data;
surface->output = output;
wlr_fractional_scale_v1_notify_scale(layer_surface->surface,
output->wlr_output->scale);
@ -566,6 +582,7 @@ handle_new_layer_surface(struct wl_listener *listener, void *data)
wlr_log(WLR_ERROR, "could not create layer surface");
return;
}
surface->tree = surface->scene_layer_surface->tree;
/* In support of IME popup */
layer_surface->surface->data = surface->scene_layer_surface->tree;

View file

@ -11,7 +11,7 @@ descriptor_destroy(struct node_descriptor *node_descriptor)
return;
}
wl_list_remove(&node_descriptor->destroy.link);
free(node_descriptor);
zfree(node_descriptor);
}
static void