From 9c0cc98d0715be917dea3bd78b9489eb73c5bf43 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 27 May 2018 12:03:36 +0100 Subject: [PATCH] Don't move empty workspaces when output is destroyed --- sway/tree/container.c | 93 ++++++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 41 deletions(-) diff --git a/sway/tree/container.c b/sway/tree/container.c index f29a9adc..8694eb33 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -176,45 +176,6 @@ static void _container_destroy(struct sway_container *cont) { free(cont); } -static struct sway_container *container_output_destroy( - struct sway_container *output) { - if (!sway_assert(output, "cannot destroy null output")) { - return NULL; - } - - if (output->children->length > 0) { - // TODO save workspaces when there are no outputs. - // TODO also check if there will ever be no outputs except for exiting - // program - if (root_container.children->length > 1) { - int p = root_container.children->items[0] == output; - // Move workspace from this output to another output - while (output->children->length) { - struct sway_container *child = output->children->items[0]; - container_remove_child(child); - container_add_child(root_container.children->items[p], child); - } - container_sort_workspaces(root_container.children->items[p]); - arrange_output(root_container.children->items[p]); - } - } - - wl_list_remove(&output->sway_output->destroy.link); - wl_list_remove(&output->sway_output->mode.link); - wl_list_remove(&output->sway_output->transform.link); - wl_list_remove(&output->sway_output->scale.link); - - wl_list_remove(&output->sway_output->damage_destroy.link); - wl_list_remove(&output->sway_output->damage_frame.link); - - // clear the wlr_output reference to this container - output->sway_output->wlr_output->data = NULL; - - wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); - _container_destroy(output); - return &root_container; -} - static struct sway_container *container_workspace_destroy( struct sway_container *workspace) { if (!sway_assert(workspace, "cannot destroy null workspace")) { @@ -232,7 +193,7 @@ static struct sway_container *container_workspace_destroy( // destroy the WS if there are no children (TODO check for floating) wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name); ipc_event_workspace(workspace, NULL, "empty"); - } else { + } else if (output) { // Move children to a different workspace on this output struct sway_container *new_workspace = NULL; // TODO move floating @@ -253,11 +214,61 @@ static struct sway_container *container_workspace_destroy( free(workspace->sway_workspace); _container_destroy(workspace); - output_damage_whole(output->sway_output); + if (output) { + output_damage_whole(output->sway_output); + } return parent; } +static struct sway_container *container_output_destroy( + struct sway_container *output) { + if (!sway_assert(output, "cannot destroy null output")) { + return NULL; + } + + if (output->children->length > 0) { + // TODO save workspaces when there are no outputs. + // TODO also check if there will ever be no outputs except for exiting + // program + if (root_container.children->length > 1) { + // Move workspace from this output to another output + struct sway_container *other_output = + root_container.children->items[0]; + if (other_output == output) { + other_output = root_container.children->items[1]; + } + + while (output->children->length) { + struct sway_container *workspace = output->children->items[0]; + container_remove_child(workspace); + if (workspace->children->length > 0) { + container_add_child(other_output, workspace); + } else { + container_workspace_destroy(workspace); + } + } + container_sort_workspaces(other_output); + arrange_output(other_output); + } + } + + wl_list_remove(&output->sway_output->destroy.link); + wl_list_remove(&output->sway_output->mode.link); + wl_list_remove(&output->sway_output->transform.link); + wl_list_remove(&output->sway_output->scale.link); + + wl_list_remove(&output->sway_output->damage_destroy.link); + wl_list_remove(&output->sway_output->damage_frame.link); + + // clear the wlr_output reference to this container + output->sway_output->wlr_output->data = NULL; + + wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); + _container_destroy(output); + return &root_container; +} + static void container_root_finish(struct sway_container *con) { wlr_log(L_ERROR, "TODO: destroy the root container"); }