commit 357d341f8fd68cd6902ea029a46baf5ce3411336
parent 14fbe9242fd43c5f58b2b55ec11bd1ead9dab3eb
Author: Kenny Levinsen <kl@kl.wtf>
Date: Thu, 31 Jul 2025 15:44:49 +0200
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.
Diffstat:
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/sway/tree/container.c b/sway/tree/container.c
@@ -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);
diff --git a/sway/tree/node.c b/sway/tree/node.c
@@ -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;
diff --git a/sway/tree/output.c b/sway/tree/output.c
@@ -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) {
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
@@ -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) {