From 84cd22c8cb722daaa9250a792da0f44930accfae Mon Sep 17 00:00:00 2001
From: Ryan Dwyer <ryandwyer1@gmail.com>
Date: Sat, 28 Jul 2018 22:13:13 +1000
Subject: Fix crash when a deferred command destroys a workspace

Example config that produces the crash (with a single output):

    workspace 1
    workspace 2

Prior to this commit, container_workspace_free would manually mark the
L_FLOATING container as destroying and free it. This assumed the
L_FLOATING container would never be involved in a transaction. This was
a safe assumption when it was implemented, but became an incorrect
assumption once parent/child relationships became transactionised.

This commit removes the L_FLOATING free from container_workspace_free.
When the workspace is destroyed, it starts the normal destroy process on
the L_FLOATING container so it can be freed via transactions.
---
 sway/tree/container.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/sway/tree/container.c b/sway/tree/container.c
index 6ebf2653..01387636 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -142,8 +142,6 @@ struct sway_container *container_create(enum sway_container_type type) {
 static void container_workspace_free(struct sway_workspace *ws) {
 	list_foreach(ws->output_priority, free);
 	list_free(ws->output_priority);
-	ws->floating->destroying = true;
-	container_free(ws->floating);
 	free(ws);
 }
 
@@ -196,6 +194,9 @@ void container_free(struct sway_container *cont) {
 	free(cont);
 }
 
+static struct sway_container *container_destroy_noreaping(
+		struct sway_container *con);
+
 static struct sway_container *container_workspace_destroy(
 		struct sway_container *workspace) {
 	if (!sway_assert(workspace, "cannot destroy null workspace")) {
@@ -240,6 +241,8 @@ static struct sway_container *container_workspace_destroy(
 		}
 	}
 
+	container_destroy_noreaping(workspace->sway_workspace->floating);
+
 	return output;
 }
 
-- 
cgit v1.2.3