diff options
Diffstat (limited to 'sway/tree')
-rw-r--r-- | sway/tree/container.c | 101 | ||||
-rw-r--r-- | sway/tree/layout.c | 58 | ||||
-rw-r--r-- | sway/tree/output.c | 36 | ||||
-rw-r--r-- | sway/tree/view.c | 11 | ||||
-rw-r--r-- | sway/tree/workspace.c | 56 |
5 files changed, 134 insertions, 128 deletions
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) { diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 73c4849b..32e6a77c 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -9,6 +9,7 @@ #include "sway/tree/container.h" #include "sway/tree/layout.h" #include "sway/output.h" +#include "sway/tree/workspace.h" #include "sway/tree/view.h" #include "sway/input/seat.h" #include "sway/ipc-server.h" @@ -99,40 +100,40 @@ void container_add_child(struct sway_container *parent, parent, parent->type, parent->width, parent->height); list_add(parent->children, child); child->parent = parent; - // set focus for this container - /* TODO WLR - if (parent->type == C_WORKSPACE && child->type == C_VIEW && - (parent->workspace_layout == L_TABBED || parent->workspace_layout == - L_STACKED)) { - child = new_container(child, parent->workspace_layout); +} + +struct sway_container *container_reap_empty(struct sway_container *container) { + if (!sway_assert(container, "reaping null container")) { + return NULL; } - */ + wlr_log(L_DEBUG, "reaping %p %s", container, container->name); + while (container->children->length == 0) { + if (container->type == C_WORKSPACE) { + if (!workspace_is_visible(container)) { + container_workspace_destroy(container); + } + break; + } else if (container->type == C_CONTAINER) { + struct sway_container *parent = container->parent; + container_destroy(container); + container = parent; + } else { + container = container->parent; + } + } + return container; } struct sway_container *container_remove_child(struct sway_container *child) { - int i; struct sway_container *parent = child->parent; - for (i = 0; i < parent->children->length; ++i) { + for (int i = 0; i < parent->children->length; ++i) { if (parent->children->items[i] == child) { list_del(parent->children, i); break; } } child->parent = NULL; - return parent; -} - -struct sway_container *container_reap_empty(struct sway_container *container) { - if (!sway_assert(container, "reaping null container")) { - return NULL; - } - while (container->children->length == 0 && container->type == C_CONTAINER) { - wlr_log(L_DEBUG, "Container: Destroying container '%p'", container); - struct sway_container *parent = container->parent; - container_destroy(container); - container = parent; - } - return container; + return container_reap_empty(parent); } void container_move_to(struct sway_container* container, @@ -145,16 +146,9 @@ void container_move_to(struct sway_container* container, container->width = container->height = 0; struct sway_container *new_parent = container_add_sibling(destination, container); - if (destination->type == C_WORKSPACE) { - // If the workspace only has one child after adding one, it - // means that the workspace was just initialized. - // TODO: Consider floating views in this test - if (destination->children->length == 1) { - ipc_event_workspace(NULL, destination, "init"); - } + if (old_parent) { + arrange_windows(old_parent, -1, -1); } - old_parent = container_reap_empty(old_parent); - arrange_windows(old_parent, -1, -1); arrange_windows(new_parent, -1, -1); } diff --git a/sway/tree/output.c b/sway/tree/output.c new file mode 100644 index 00000000..2246cb11 --- /dev/null +++ b/sway/tree/output.c @@ -0,0 +1,36 @@ +#include "sway/tree/container.h" +#include "sway/tree/layout.h" +#include "sway/output.h" +#include "log.h" + +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; +} diff --git a/sway/tree/view.c b/sway/tree/view.c index d5325c31..480ff693 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -3,6 +3,7 @@ #include "sway/tree/container.h" #include "sway/tree/layout.h" #include "sway/tree/view.h" +#include "log.h" const char *view_get_title(struct sway_view *view) { if (view->iface.get_prop) { @@ -94,3 +95,13 @@ void view_update_outputs(struct sway_view *view, const struct wlr_box *before) { } } } + +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 = container_destroy(view); + arrange_windows(parent, -1, -1); + return parent; +} diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 5800ea09..c629f1f1 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -6,9 +6,10 @@ #include <stdio.h> #include <strings.h> #include "stringop.h" -#include "sway/tree/container.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" +#include "sway/ipc-server.h" +#include "sway/tree/container.h" #include "sway/tree/workspace.h" #include "log.h" #include "util.h" @@ -202,7 +203,48 @@ struct sway_container *workspace_create(const char *name) { sway_seat_get_focus_inactive(seat, &root_container); parent = focus; parent = container_parent(parent, C_OUTPUT); - return container_workspace_create(parent, name); + struct sway_container *new_ws = container_workspace_create(parent, name); + ipc_event_workspace(NULL, new_ws, "init"); + return new_ws; +} + +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; } /** @@ -343,3 +385,13 @@ bool workspace_switch(struct sway_container *workspace) { arrange_windows(output, -1, -1); return true; } + +bool workspace_is_visible(struct sway_container *ws) { + struct sway_container *output = container_parent(ws, C_OUTPUT); + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = sway_seat_get_focus_inactive(seat, output); + if (focus->type != C_WORKSPACE) { + focus = container_parent(focus, C_WORKSPACE); + } + return focus == ws; +} |