tree/node: Do not mark destroying nodes as dirty

Node destruction currently runs through the transaction system such that
a particular node is only destroyed after its use in an ongoing
transaction. If a node is dirtied after the node is marked as destroying
but before it is destroyed, the pointer added to dirty_nodes would
become a dangling pointer once the node was destroyed.

Do not dirty destroying nodes, and ensure that destroying is only set
after the last dirty.
This commit is contained in:
Kenny Levinsen 2025-07-31 15:44:49 +02:00 committed by Simon Ser
parent 14fbe9242f
commit 357d341f8f
4 changed files with 4 additions and 4 deletions

View file

@ -547,8 +547,8 @@ void container_begin_destroy(struct sway_container *con) {
container_end_mouse_operation(con);
con->node.destroying = true;
node_set_dirty(&con->node);
con->node.destroying = true;
if (con->scratchpad) {
root_scratchpad_remove_container(con);

View file

@ -29,7 +29,7 @@ const char *node_type_to_str(enum sway_node_type type) {
}
void node_set_dirty(struct sway_node *node) {
if (node->dirty) {
if (node->dirty || node->destroying) {
return;
}
node->dirty = true;

View file

@ -301,8 +301,8 @@ void output_begin_destroy(struct sway_output *output) {
sway_log(SWAY_DEBUG, "Destroying output '%s'", output->wlr_output->name);
wl_signal_emit_mutable(&output->node.events.destroy, &output->node);
output->node.destroying = true;
node_set_dirty(&output->node);
output->node.destroying = true;
}
struct sway_output *output_from_wlr_output(struct wlr_output *output) {

View file

@ -166,8 +166,8 @@ void workspace_begin_destroy(struct sway_workspace *workspace) {
if (workspace->output) {
workspace_detach(workspace);
}
workspace->node.destroying = true;
node_set_dirty(&workspace->node);
workspace->node.destroying = true;
}
void workspace_consider_destroy(struct sway_workspace *ws) {