mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
layers: don't send configure events in unmap handler
Alternative to7bf08afwhich was reverted in the previous commit.7bf08affixed the problem that layer-shell clients are terminated when it's unmapped, by sending configure events in node-destroy handler rather than in unmap handler. But it caused a UAF bug when an output with layer-shell clients is destroyed. So this patch fixes the original issue by simply skipping the surface in arrange_one_layer() if it's being unmapped.
This commit is contained in:
parent
cc0fe78ceb
commit
6f70cd0d6e
2 changed files with 19 additions and 0 deletions
|
|
@ -14,6 +14,8 @@ struct lab_layer_surface {
|
|||
struct server *server;
|
||||
|
||||
bool mapped;
|
||||
/* true only inside handle_unmap() */
|
||||
bool being_unmapped;
|
||||
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
|
|
|
|||
17
src/layers.c
17
src/layers.c
|
|
@ -50,6 +50,9 @@ arrange_one_layer(const struct wlr_box *full_area, struct wlr_box *usable_area,
|
|||
if (!scene->layer_surface->initialized) {
|
||||
continue;
|
||||
}
|
||||
if (surface->being_unmapped) {
|
||||
continue;
|
||||
}
|
||||
if (!!scene->layer_surface->current.exclusive_zone != exclusive) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -343,6 +346,18 @@ 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 we send a configure event in unmap handler, the layer-shell
|
||||
* client sends ack_configure back and wlroots posts a
|
||||
* "wrong configure serial" error, which terminates the client (see
|
||||
* https://github.com/labwc/labwc/pull/1154#issuecomment-2906885183).
|
||||
*
|
||||
* To prevent this, we set being_unmapped here and check it in
|
||||
* arrange_one_layer() called by output_update_usable_area().
|
||||
*/
|
||||
layer->being_unmapped = true;
|
||||
|
||||
if (layer_surface->output) {
|
||||
output_update_usable_area(layer_surface->output->data);
|
||||
}
|
||||
|
|
@ -350,6 +365,8 @@ handle_unmap(struct wl_listener *listener, void *data)
|
|||
if (seat->focused_layer == layer_surface) {
|
||||
try_to_focus_next_layer_or_toplevel(layer->server);
|
||||
}
|
||||
|
||||
layer->being_unmapped = false;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue