diff --git a/include/focus.h b/include/focus.h index 4abd60806..602b61222 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 1d21ac352..0d9ee7e3e 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 647f97714..4336b6c72 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); @@ -226,8 +247,8 @@ static bool handle_view_created(wlc_handle handle) { // using newview as a temp storage location here, // rather than adding yet another workspace var newview = workspace_for_pid(pid); - if (newview && newview != current_ws) { - focused = newview; + if (newview) { + focused = get_focused_container(newview); return_to_workspace = true; } newview = NULL; @@ -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; }