From c503bf13426aa269779e81567e3b36ada56dabc1 Mon Sep 17 00:00:00 2001
From: Mykyta Holubakha <hilobakho@gmail.com>
Date: Mon, 11 Jul 2016 22:27:13 +0300
Subject: [PATCH] Suspend destruction of wss when creating views

---
 include/focus.h |  2 ++
 sway/focus.c    |  3 ++-
 sway/handlers.c | 27 +++++++++++++++++++++++++++
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/include/focus.h b/include/focus.h
index 4abd6080..602b6122 100644
--- a/include/focus.h
+++ b/include/focus.h
@@ -34,6 +34,8 @@ bool set_focused_container_for(swayc_t *ancestor, swayc_t *container);
 extern bool locked_container_focus;
 extern bool locked_view_focus;
 
+// Prevents wss from being destroyed on focus switch
+extern bool suspend_workspace_cleanup;
 
 bool move_focus(enum movement_direction direction);
 
diff --git a/sway/focus.c b/sway/focus.c
index 1d21ac35..0d9ee7e3 100644
--- a/sway/focus.c
+++ b/sway/focus.c
@@ -11,6 +11,7 @@
 
 bool locked_container_focus = false;
 bool locked_view_focus = false;
+bool suspend_workspace_cleanup = false;
 
 // switches parent focus to c. will switch it accordingly
 static void update_focus(swayc_t *c) {
@@ -40,7 +41,7 @@ static void update_focus(swayc_t *c) {
 				ipc_event_workspace(prev, c, "focus");
 
 				// if the old workspace has no children, destroy it
-				if(prev->children->length == 0 && prev->floating->length == 0){
+				if(prev->children->length == 0 && prev->floating->length == 0 && !suspend_workspace_cleanup) {
 					destroy_workspace(prev);
 				} else {
 					// update visibility of old workspace
diff --git a/sway/handlers.c b/sway/handlers.c
index e322c579..4336b6c7 100644
--- a/sway/handlers.c
+++ b/sway/handlers.c
@@ -198,6 +198,27 @@ static bool client_is_panel(struct wl_client *client) {
 	return false;
 }
 
+static void ws_cleanup() {
+	swayc_t *op, *ws;
+	int i = 0, j;
+	if (!root_container.children)
+		return;
+	while (i < root_container.children->length) {
+		op = root_container.children->items[i++];
+		if (!op->children)
+			continue;
+		j = 0;
+		while (j < op->children->length) {
+			ws = op->children->items[j++];
+			if (ws->children->length == 0 && ws->floating->length == 0 && ws != op->focused) {
+				if (destroy_workspace(ws)) {
+					j--;
+				}
+			}
+		}
+	}
+}
+
 static bool handle_view_created(wlc_handle handle) {
 	// if view is child of another view, the use that as focused container
 	wlc_handle parent = wlc_view_get_parent(handle);
@@ -295,6 +316,9 @@ static bool handle_view_created(wlc_handle handle) {
 		break;
 	}
 
+	// Prevent current ws from being destroyed, if empty
+	suspend_workspace_cleanup = true;
+
 	if (newview) {
 		set_focused_container(newview);
 		swayc_t *output = swayc_parent_by_type(newview, C_OUTPUT);
@@ -343,6 +367,9 @@ static bool handle_view_created(wlc_handle handle) {
 		workspace_switch(current_ws);
 		set_focused_container(current_ws->focused);
 	}
+
+	suspend_workspace_cleanup = false;
+	ws_cleanup();
 	return true;
 }