From 01af34391267e91461a4ab7a1234dd58f45d2c93 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 30 Mar 2018 10:31:21 -0400 Subject: Destroy empty workspaces when moving away --- sway/tree/container.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) (limited to 'sway/tree/container.c') diff --git a/sway/tree/container.c b/sway/tree/container.c index 2eac812e..ed39a154 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -58,7 +58,7 @@ static struct sway_container *container_create(enum sway_container_type type) { return c; } -static void container_destroy(struct sway_container *cont) { +void container_destroy(struct sway_container *cont) { if (cont == NULL) { return; } @@ -203,8 +203,7 @@ struct sway_container *container_view_create(struct sway_container *sibling, } struct sway_container *container_output_destroy(struct sway_container *output) { - if (!sway_assert(output, - "null output passed to container_output_destroy")) { + if (!sway_assert(output, "cannot destroy null output")) { return NULL; } @@ -236,6 +235,45 @@ struct sway_container *container_output_destroy(struct sway_container *output) { return &root_container; } +struct sway_container *container_workspace_destroy( + struct sway_container *workspace) { + if (!sway_assert(workspace, "cannot destroy null workspace")) { + return NULL; + } + + // Do not destroy this if it's the last workspace on this output + struct sway_container *output = container_parent(workspace, C_OUTPUT); + if (output && output->children->length == 1) { + return NULL; + } + + struct sway_container *parent = workspace->parent; + if (workspace->children->length == 0) { + // 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 { + // Move children to a different workspace on this output + struct sway_container *new_workspace = NULL; + // TODO move floating + for (int i = 0; i < output->children->length; i++) { + if (output->children->items[i] != workspace) { + new_workspace = output->children->items[i]; + break; + } + } + + wlr_log(L_DEBUG, "moving children to different workspace '%s' -> '%s'", + workspace->name, new_workspace->name); + for (int i = 0; i < workspace->children->length; i++) { + container_move_to(workspace->children->items[i], new_workspace); + } + } + + container_destroy(workspace); + return parent; +} + struct sway_container *container_view_destroy(struct sway_container *view) { if (!view) { return NULL; @@ -438,3 +476,14 @@ void container_for_each_descendant_bfs(struct sway_container *con, list_cat(queue, current->children); } } + +bool container_has_anscestor(struct sway_container *descendant, + struct sway_container *anscestor) { + while (descendant->type != C_ROOT) { + descendant = descendant->parent; + if (descendant == anscestor) { + return true; + } + } + return false; +} -- cgit v1.2.3 From 49379dd0fc0758f89d7f4fa4fb5b08c7f4c26ae6 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 30 Mar 2018 11:58:17 -0400 Subject: Fix workspace deletion edge cases --- sway/tree/container.c | 101 ++++---------------------------------------------- 1 file changed, 7 insertions(+), 94 deletions(-) (limited to 'sway/tree/container.c') diff --git a/sway/tree/container.c b/sway/tree/container.c index ed39a154..778108b4 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -10,12 +10,12 @@ #include "sway/tree/container.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" -#include "sway/tree/layout.h" +#include "sway/ipc-server.h" #include "sway/output.h" #include "sway/server.h" +#include "sway/tree/layout.h" #include "sway/tree/view.h" #include "sway/tree/workspace.h" -#include "sway/ipc-server.h" #include "log.h" static list_t *bfs_queue; @@ -58,13 +58,14 @@ static struct sway_container *container_create(enum sway_container_type type) { return c; } -void container_destroy(struct sway_container *cont) { +struct sway_container *container_destroy(struct sway_container *cont) { if (cont == NULL) { - return; + return NULL; } wl_signal_emit(&cont->events.destroy, cont); + struct sway_container *parent = cont->parent; if (cont->children) { // remove children until there are no more, container_destroy calls // container_remove_child, which removes child from this container @@ -77,13 +78,14 @@ void container_destroy(struct sway_container *cont) { list_foreach(cont->marks, free); list_free(cont->marks); } - if (cont->parent) { + if (parent) { container_remove_child(cont); } if (cont->name) { free(cont->name); } free(cont); + return parent; } struct sway_container *container_output_create( @@ -202,95 +204,6 @@ struct sway_container *container_view_create(struct sway_container *sibling, return swayc; } -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_windows(root_container.children->items[p], - -1, -1); - } - } - - wl_list_remove(&output->sway_output->frame.link); - wl_list_remove(&output->sway_output->destroy.link); - wl_list_remove(&output->sway_output->mode.link); - - wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); - container_destroy(output); - - return &root_container; -} - -struct sway_container *container_workspace_destroy( - struct sway_container *workspace) { - if (!sway_assert(workspace, "cannot destroy null workspace")) { - return NULL; - } - - // Do not destroy this if it's the last workspace on this output - struct sway_container *output = container_parent(workspace, C_OUTPUT); - if (output && output->children->length == 1) { - return NULL; - } - - struct sway_container *parent = workspace->parent; - if (workspace->children->length == 0) { - // 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 { - // Move children to a different workspace on this output - struct sway_container *new_workspace = NULL; - // TODO move floating - for (int i = 0; i < output->children->length; i++) { - if (output->children->items[i] != workspace) { - new_workspace = output->children->items[i]; - break; - } - } - - wlr_log(L_DEBUG, "moving children to different workspace '%s' -> '%s'", - workspace->name, new_workspace->name); - for (int i = 0; i < workspace->children->length; i++) { - container_move_to(workspace->children->items[i], new_workspace); - } - } - - container_destroy(workspace); - return parent; -} - -struct sway_container *container_view_destroy(struct sway_container *view) { - if (!view) { - return NULL; - } - wlr_log(L_DEBUG, "Destroying view '%s'", view->name); - struct sway_container *parent = view->parent; - container_destroy(view); - - // TODO WLR: Destroy empty containers - /* - if (parent && parent->type == C_CONTAINER) { - return destroy_container(parent); - } - */ - return parent; -} - struct sway_container *container_set_layout(struct sway_container *container, enum sway_container_layout layout) { if (container->type == C_WORKSPACE) { -- cgit v1.2.3 From 88f08a42f30c6d79adbc9c1d5d897113fcd3a6f4 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 30 Mar 2018 14:31:17 -0400 Subject: Fix segfault when reaping invisible workspaces --- sway/tree/container.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/tree/container.c') diff --git a/sway/tree/container.c b/sway/tree/container.c index 778108b4..c3cf6c64 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -79,7 +79,7 @@ struct sway_container *container_destroy(struct sway_container *cont) { list_free(cont->marks); } if (parent) { - container_remove_child(cont); + parent = container_remove_child(cont); } if (cont->name) { free(cont->name); -- cgit v1.2.3 From a776ecbb860608e0f75430a53ea75a6ed19ac746 Mon Sep 17 00:00:00 2001 From: emersion Date: Fri, 30 Mar 2018 13:18:50 -0400 Subject: Add lite damage tracking This skips the renderer if nothing has changed, and renders everything otherwise. --- sway/tree/container.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/tree/container.c') diff --git a/sway/tree/container.c b/sway/tree/container.c index c3cf6c64..8705edc7 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -6,8 +6,8 @@ #include #include #include +#include "log.h" #include "sway/config.h" -#include "sway/tree/container.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" #include "sway/ipc-server.h" -- cgit v1.2.3