sway/tree: Simplify sway_node teardown

A sway_node may end up being referenced in either a queued transaction,
pending transaction or as a dirty node. To manage this, the transaction
system has been responsible for destroying containers, workspaces and
outputs at the end of their last referenced transaction.

This significantly complicates the teardown flow of surfaces and
outputs. Instead, remove the node from transactions and dirty lists so
that the callsite can remove and free the node immediately.
This commit is contained in:
Kenny Levinsen 2025-05-26 14:19:17 +02:00 committed by Simon Ser
parent 4f59eeef05
commit e28e6484e8
16 changed files with 125 additions and 149 deletions

View file

@ -70,11 +70,10 @@ bool view_init(struct sway_view *view, enum sway_view_type type,
}
void view_destroy(struct sway_view *view) {
if (!sway_assert(view->surface == NULL, "Tried to free mapped view")) {
if (!sway_assert(view->surface == NULL, "Tried to destroy a mapped view")) {
return;
}
if (!sway_assert(view->destroying,
"Tried to free view which wasn't marked as destroying")) {
if (!sway_assert(view->surface == NULL, "Tried to free mapped view")) {
return;
}
if (!sway_assert(view->container == NULL,
@ -95,17 +94,6 @@ void view_destroy(struct sway_view *view) {
}
}
void view_begin_destroy(struct sway_view *view) {
if (!sway_assert(view->surface == NULL, "Tried to destroy a mapped view")) {
return;
}
view->destroying = true;
if (!view->container) {
view_destroy(view);
}
}
const char *view_get_title(struct sway_view *view) {
if (view->impl->get_string_prop) {
return view->impl->get_string_prop(view, VIEW_PROP_TITLE);
@ -935,17 +923,19 @@ void view_unmap(struct sway_view *view) {
struct sway_container *parent = view->container->pending.parent;
struct sway_workspace *ws = view->container->pending.workspace;
container_begin_destroy(view->container);
container_destroy(view->container);
if (parent) {
container_reap_empty(parent);
} else if (ws) {
workspace_consider_destroy(ws);
if (workspace_consider_destroy(ws)) {
ws = NULL;
}
}
if (root->fullscreen_global) {
// Container may have been a child of the root fullscreen container
arrange_root();
} else if (ws && !ws->node.destroying) {
} else if (ws) {
arrange_workspace(ws);
workspace_detect_urgent(ws);
}
@ -1099,9 +1089,6 @@ void view_update_title(struct sway_view *view, bool force) {
}
bool view_is_visible(struct sway_view *view) {
if (view->container->node.destroying) {
return false;
}
struct sway_workspace *workspace = view->container->pending.workspace;
if (!workspace && view->container->pending.fullscreen_mode != FULLSCREEN_GLOBAL) {
bool fs_global_descendant = false;