From 2c165e1288cbb60f5e677595e35f58a9c56c7010 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 2 Apr 2018 21:01:33 -0400 Subject: [PATCH 01/21] fix more close segfaults --- include/sway/tree/container.h | 2 ++ sway/commands/kill.c | 5 +---- sway/tree/container.c | 37 ++++++++++++++++++++++++++++++++++- sway/tree/layout.c | 2 +- sway/tree/view.c | 2 +- 5 files changed, 41 insertions(+), 7 deletions(-) diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 464f80c4..5d15f12b 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -134,6 +134,8 @@ struct sway_container *container_workspace_destroy(struct sway_container *contai struct sway_container *container_output_destroy(struct sway_container *container); struct sway_container *container_view_destroy(struct sway_container *container); +struct sway_container *container_close(struct sway_container *container); + // TODO move to layout.c struct sway_container *container_set_layout(struct sway_container *container, enum sway_container_layout layout); diff --git a/sway/commands/kill.c b/sway/commands/kill.c index 46d6e98e..811c3e6b 100644 --- a/sway/commands/kill.c +++ b/sway/commands/kill.c @@ -19,11 +19,8 @@ struct cmd_results *cmd_kill(int argc, char **argv) { "Can only kill views and containers with this command"); break; case C_CONTAINER: - con = container_destroy(con); - arrange_windows(con, -1, -1); - break; case C_VIEW: - view_close(con->sway_view); + container_close(con); break; } diff --git a/sway/tree/container.c b/sway/tree/container.c index 4db93ce8..8688edd6 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -112,10 +112,45 @@ static struct sway_container *_container_destroy(struct sway_container *cont) { struct sway_container *container_destroy(struct sway_container *cont) { struct sway_container *parent = _container_destroy(cont); parent = container_reap_empty(parent); - arrange_windows(&root_container, -1, -1); return parent; } +static void container_close_func(struct sway_container *container, void *data) { + if (container->type == C_VIEW) { + view_close(container->sway_view); + } +} + +struct sway_container *container_close(struct sway_container *con) { + if (!sway_assert(con != NULL, "container_close called with a NULL container")) { + return NULL; + } + + switch (con->type) { + case C_TYPES: + wlr_log(L_ERROR, "tried to close an invalid container"); + break; + case C_ROOT: + wlr_log(L_ERROR, "tried to close the root container"); + break; + case C_OUTPUT: + container_output_destroy(con); + break; + case C_WORKSPACE: + container_workspace_destroy(con); + break; + case C_CONTAINER: + container_for_each_descendant_dfs(con, container_close_func, NULL); + break; + case C_VIEW: + view_close(con->sway_view); + break; + + } + + return con->parent; +} + struct sway_container *container_output_create( struct sway_output *sway_output) { struct wlr_box size; diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 95a84d12..b0ce4aaf 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -110,7 +110,7 @@ struct sway_container *container_reap_empty(struct sway_container *container) { wlr_log(L_DEBUG, "Reaping %p %s '%s'", container, container_type_to_str(container->type), container->name); while (container->type != C_ROOT && container->type != C_OUTPUT - && container->children->length == 0) { + && container->children && container->children->length == 0) { if (container->type == C_WORKSPACE) { if (!workspace_is_visible(container)) { struct sway_container *parent = container->parent; diff --git a/sway/tree/view.c b/sway/tree/view.c index 09c804e4..4e695b5f 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -84,7 +84,7 @@ struct sway_container *container_view_destroy(struct sway_container *view) { } wlr_log(L_DEBUG, "Destroying view '%s'", view->name); struct sway_container *parent = container_destroy(view); - arrange_windows(parent, -1, -1); + arrange_windows(&root_container, -1, -1); return parent; } From 2992b72d61933568476e2bf4baf573e714f9ed40 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 2 Apr 2018 22:37:21 -0400 Subject: [PATCH 02/21] change reap container approach --- include/sway/tree/container.h | 4 +-- include/sway/tree/layout.h | 4 ++- sway/tree/container.c | 54 ++++++++++++++++++++++++++++++++--- sway/tree/layout.c | 29 ++----------------- sway/tree/view.c | 10 +++---- 5 files changed, 63 insertions(+), 38 deletions(-) diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 5d15f12b..1286316a 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -128,11 +128,11 @@ struct sway_container *container_view_create( struct sway_container *sibling, struct sway_view *sway_view); // TODO don't return the parent on destroy -struct sway_container *container_destroy(struct sway_container *container); +void container_destroy(struct sway_container *container); struct sway_container *container_workspace_destroy(struct sway_container *container); struct sway_container *container_output_destroy(struct sway_container *container); -struct sway_container *container_view_destroy(struct sway_container *container); +void container_view_destroy(struct sway_container *container); struct sway_container *container_close(struct sway_container *container); diff --git a/include/sway/tree/layout.h b/include/sway/tree/layout.h index 8badb244..9d33d561 100644 --- a/include/sway/tree/layout.h +++ b/include/sway/tree/layout.h @@ -41,7 +41,9 @@ struct sway_container *container_add_sibling(struct sway_container *parent, struct sway_container *container_remove_child(struct sway_container *child); // TODO PRIVATE in tree.h -struct sway_container *container_reap_empty(struct sway_container *container); + +struct sway_container *container_replace_child(struct sway_container *child, + struct sway_container *new_child); // TODO move to tree.h void container_move_to(struct sway_container* container, diff --git a/sway/tree/container.c b/sway/tree/container.c index 8688edd6..686a52c7 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -1,4 +1,5 @@ #define _POSIX_C_SOURCE 200809L +#include #include #include #include @@ -109,12 +110,55 @@ static struct sway_container *_container_destroy(struct sway_container *cont) { return parent; } -struct sway_container *container_destroy(struct sway_container *cont) { - struct sway_container *parent = _container_destroy(cont); - parent = container_reap_empty(parent); +static void reap_empty_func(struct sway_container *con, void *data) { + switch (con->type) { + case C_TYPES: + case C_ROOT: + case C_OUTPUT: + // dont reap these + break; + case C_WORKSPACE: + if (!workspace_is_visible(con) && con->children->length == 0) { + container_workspace_destroy(con); + } + break; + case C_CONTAINER: + if (con->children->length == 0) { + _container_destroy(con); + } else if (con->children->length == 1) { + struct sway_container *only_child = con->children->items[0]; + if (only_child->type == C_CONTAINER) { + container_remove_child(only_child); + container_replace_child(con, only_child); + _container_destroy(con); + } + } + case C_VIEW: + break; + } +} + +struct sway_container *container_reap_empty(struct sway_container *container) { + struct sway_container *parent = container->parent; + + container_for_each_descendant_dfs(container, reap_empty_func, NULL); + return parent; } +void container_destroy(struct sway_container *cont) { + if (cont == NULL) { + return; + } + + if (cont->children != NULL && cont->children->length) { + assert(false && "dont destroy containers with children"); + } + + _container_destroy(cont); + container_reap_empty(&root_container); +} + static void container_close_func(struct sway_container *container, void *data) { if (container->type == C_VIEW) { view_close(container->sway_view); @@ -126,6 +170,8 @@ struct sway_container *container_close(struct sway_container *con) { return NULL; } + struct sway_container *parent = con->parent; + switch (con->type) { case C_TYPES: wlr_log(L_ERROR, "tried to close an invalid container"); @@ -148,7 +194,7 @@ struct sway_container *container_close(struct sway_container *con) { } - return con->parent; + return parent; } struct sway_container *container_output_create( diff --git a/sway/tree/layout.c b/sway/tree/layout.c index b0ce4aaf..79470f98 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -103,32 +103,6 @@ void container_add_child(struct sway_container *parent, child->parent = parent; } -struct sway_container *container_reap_empty(struct sway_container *container) { - if (container == NULL) { - return NULL; - } - wlr_log(L_DEBUG, "Reaping %p %s '%s'", container, - container_type_to_str(container->type), container->name); - while (container->type != C_ROOT && container->type != C_OUTPUT - && container->children && container->children->length == 0) { - if (container->type == C_WORKSPACE) { - if (!workspace_is_visible(container)) { - struct sway_container *parent = container->parent; - container_workspace_destroy(container); - return parent; - } - return container; - } 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) { struct sway_container *parent = child->parent; for (int i = 0; i < parent->children->length; ++i) { @@ -309,6 +283,8 @@ void arrange_windows(struct sway_container *container, container->children->length); break; case L_VERT: + assert(container); + assert(container->children); apply_vert_layout(container, x, y, width, height, 0, container->children->length); break; @@ -381,6 +357,7 @@ void apply_vert_layout(struct sway_container *container, const double x, const double y, const double width, const double height, const int start, const int end) { + assert(container); int i; double scale = 0; // Calculate total height diff --git a/sway/tree/view.c b/sway/tree/view.c index 4e695b5f..eeadc5d8 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -78,14 +78,12 @@ void view_close(struct sway_view *view) { } } -struct sway_container *container_view_destroy(struct sway_container *view) { +void container_view_destroy(struct sway_container *view) { if (!view) { - return NULL; + return; } wlr_log(L_DEBUG, "Destroying view '%s'", view->name); - struct sway_container *parent = container_destroy(view); - arrange_windows(&root_container, -1, -1); - return parent; + container_destroy(view); } void view_damage_whole(struct sway_view *view) { @@ -164,6 +162,8 @@ void view_unmap(struct sway_view *view) { view->swayc = NULL; view->surface = NULL; + + arrange_windows(&root_container, -1, -1); } void view_update_position(struct sway_view *view, double ox, double oy) { From 20f9d49b824fdb7118eab6f559d45b95ecac9331 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 2 Apr 2018 22:42:44 -0400 Subject: [PATCH 03/21] cleanup --- sway/tree/layout.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 79470f98..487f895f 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -1,5 +1,4 @@ #define _POSIX_C_SOURCE 200809L -#include #include #include #include @@ -283,8 +282,6 @@ void arrange_windows(struct sway_container *container, container->children->length); break; case L_VERT: - assert(container); - assert(container->children); apply_vert_layout(container, x, y, width, height, 0, container->children->length); break; @@ -357,7 +354,6 @@ void apply_vert_layout(struct sway_container *container, const double x, const double y, const double width, const double height, const int start, const int end) { - assert(container); int i; double scale = 0; // Calculate total height From 33006c4e64c7f12ecb7dc199f0452712a520860b Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 2 Apr 2018 23:15:19 -0400 Subject: [PATCH 04/21] dont deallocate in container_close --- sway/tree/container.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sway/tree/container.c b/sway/tree/container.c index 686a52c7..cb407f0e 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -174,17 +174,9 @@ struct sway_container *container_close(struct sway_container *con) { switch (con->type) { case C_TYPES: - wlr_log(L_ERROR, "tried to close an invalid container"); - break; case C_ROOT: - wlr_log(L_ERROR, "tried to close the root container"); - break; case C_OUTPUT: - container_output_destroy(con); - break; case C_WORKSPACE: - container_workspace_destroy(con); - break; case C_CONTAINER: container_for_each_descendant_dfs(con, container_close_func, NULL); break; From 7afbe9284ff1ca2eece6da1838061cad9ed655e0 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 11:27:27 -0400 Subject: [PATCH 05/21] rename _container_destroy to container_finish --- sway/tree/container.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sway/tree/container.c b/sway/tree/container.c index cb407f0e..d9fc61e7 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -77,7 +77,7 @@ struct sway_container *container_create(enum sway_container_type type) { return c; } -static struct sway_container *_container_destroy(struct sway_container *cont) { +static struct sway_container *container_finish(struct sway_container *cont) { if (cont == NULL) { return NULL; } @@ -124,13 +124,13 @@ static void reap_empty_func(struct sway_container *con, void *data) { break; case C_CONTAINER: if (con->children->length == 0) { - _container_destroy(con); + container_finish(con); } else if (con->children->length == 1) { struct sway_container *only_child = con->children->items[0]; if (only_child->type == C_CONTAINER) { container_remove_child(only_child); container_replace_child(con, only_child); - _container_destroy(con); + container_finish(con); } } case C_VIEW: @@ -146,6 +146,7 @@ struct sway_container *container_reap_empty(struct sway_container *container) { return parent; } + void container_destroy(struct sway_container *cont) { if (cont == NULL) { return; @@ -155,7 +156,7 @@ void container_destroy(struct sway_container *cont) { assert(false && "dont destroy containers with children"); } - _container_destroy(cont); + container_finish(cont); container_reap_empty(&root_container); } From b4c5f79725142c78a398a22981392d645bc9d2e9 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 12:25:19 -0400 Subject: [PATCH 06/21] move view and workspace destructors to container.c --- include/sway/tree/container.h | 7 +-- sway/input/seat.c | 3 +- sway/tree/container.c | 83 +++++++++++++++++++++++++++++++---- sway/tree/view.c | 13 +----- sway/tree/workspace.c | 39 ---------------- 5 files changed, 83 insertions(+), 62 deletions(-) diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 1286316a..278505ce 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -128,11 +128,12 @@ struct sway_container *container_view_create( struct sway_container *sibling, struct sway_view *sway_view); // TODO don't return the parent on destroy -void container_destroy(struct sway_container *container); +struct sway_container *container_destroy(struct sway_container *container); + +// TODO make me private +struct sway_container *container_finish(struct sway_container *cont); -struct sway_container *container_workspace_destroy(struct sway_container *container); struct sway_container *container_output_destroy(struct sway_container *container); -void container_view_destroy(struct sway_container *container); struct sway_container *container_close(struct sway_container *container); diff --git a/sway/input/seat.c b/sway/input/seat.c index c41f7b2e..d752acb8 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -381,7 +381,8 @@ void seat_set_focus_warp(struct sway_seat *seat, if (last_ws) { ipc_event_workspace(last_ws, container, "focus"); if (last_ws->children->length == 0) { - container_workspace_destroy(last_ws); + output_damage_whole(last_ws->parent->sway_output); + container_destroy(last_ws); } } struct sway_container *last_output = last_focus; diff --git a/sway/tree/container.c b/sway/tree/container.c index d9fc61e7..c1ebf4f1 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -77,7 +77,7 @@ struct sway_container *container_create(enum sway_container_type type) { return c; } -static struct sway_container *container_finish(struct sway_container *cont) { +struct sway_container *container_finish(struct sway_container *cont) { if (cont == NULL) { return NULL; } @@ -91,7 +91,7 @@ static struct sway_container *container_finish(struct sway_container *cont) { while (cont->children != NULL && cont->children->length != 0) { struct sway_container *child = cont->children->items[0]; container_remove_child(child); - container_destroy(child); + container_finish(child); } } if (cont->marks) { @@ -109,6 +109,45 @@ static struct sway_container *container_finish(struct sway_container *cont) { free(cont); return parent; } +static 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_finish(workspace); + return parent; +} + static void reap_empty_func(struct sway_container *con, void *data) { switch (con->type) { @@ -146,18 +185,46 @@ struct sway_container *container_reap_empty(struct sway_container *container) { return parent; } +static void container_root_finish(struct sway_container *con) { + wlr_log(L_ERROR, "TODO: destroy the root container"); +} -void container_destroy(struct sway_container *cont) { - if (cont == NULL) { - return; +struct sway_container *container_destroy(struct sway_container *con) { + if (con == NULL) { + return NULL; } - if (cont->children != NULL && cont->children->length) { - assert(false && "dont destroy containers with children"); + struct sway_container *anscestor = NULL; + + switch (con->type) { + case C_ROOT: + container_root_finish(con); + break; + case C_OUTPUT: + anscestor = container_output_destroy(con); + break; + case C_WORKSPACE: + anscestor = container_workspace_destroy(con); + break; + case C_CONTAINER: + if (con->children != NULL && con->children->length) { + assert(false && "dont destroy container containers with children"); + } + container_finish(con); + // TODO return parent to arrange maybe? + break; + case C_VIEW: + container_finish(con); + // TODO return parent to arrange maybe? + break; + case C_TYPES: + wlr_log(L_ERROR, "tried to destroy an invalid container"); + break; } - container_finish(cont); container_reap_empty(&root_container); + + return anscestor; } static void container_close_func(struct sway_container *container, void *data) { diff --git a/sway/tree/view.c b/sway/tree/view.c index eeadc5d8..c06924f5 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -27,8 +27,7 @@ void view_destroy(struct sway_view *view) { view_unmap(view); } - container_view_destroy(view->swayc); - free(view); + container_destroy(view->swayc); } const char *view_get_title(struct sway_view *view) { @@ -78,14 +77,6 @@ void view_close(struct sway_view *view) { } } -void container_view_destroy(struct sway_container *view) { - if (!view) { - return; - } - wlr_log(L_DEBUG, "Destroying view '%s'", view->name); - container_destroy(view); -} - void view_damage_whole(struct sway_view *view) { for (int i = 0; i < root_container.children->length; ++i) { struct sway_container *cont = root_container.children->items[i]; @@ -158,7 +149,7 @@ void view_unmap(struct sway_view *view) { view_damage_whole(view); - container_view_destroy(view->swayc); + container_destroy(view->swayc); view->swayc = NULL; view->surface = NULL; diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 74330884..7d180009 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -208,45 +208,6 @@ struct sway_container *workspace_create(const char *name) { 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; -} - /** * Get the previous or next workspace on the specified output. Wraps around at * the end and beginning. If next is false, the previous workspace is returned, From 09d448ea2df60b7e4504b1ec4728e7f1df0244b7 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 12:34:01 -0400 Subject: [PATCH 07/21] unify container destroy functions --- include/sway/tree/container.h | 2 -- sway/config/output.c | 2 +- sway/desktop/output.c | 4 ++-- sway/tree/container.c | 37 +++++++++++++++++++++++++++++++++++ sway/tree/output.c | 36 ---------------------------------- 5 files changed, 40 insertions(+), 41 deletions(-) diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 278505ce..c6393dc0 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -133,8 +133,6 @@ struct sway_container *container_destroy(struct sway_container *container); // TODO make me private struct sway_container *container_finish(struct sway_container *cont); -struct sway_container *container_output_destroy(struct sway_container *container); - struct sway_container *container_close(struct sway_container *container); // TODO move to layout.c diff --git a/sway/config/output.c b/sway/config/output.c index b4e56efa..c4b74ce2 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -127,7 +127,7 @@ void apply_output_config(struct output_config *oc, struct sway_container *output if (oc && oc->enabled == 0) { wlr_output_layout_remove(root_container.sway_root->output_layout, wlr_output); - container_output_destroy(output); + container_destroy(output); return; } diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 10ed1f6d..a1f89cf9 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -338,12 +338,12 @@ void output_damage_whole_view(struct sway_output *output, static void damage_handle_destroy(struct wl_listener *listener, void *data) { struct sway_output *output = wl_container_of(listener, output, damage_destroy); - container_output_destroy(output->swayc); + container_destroy(output->swayc); } static void handle_destroy(struct wl_listener *listener, void *data) { struct sway_output *output = wl_container_of(listener, output, destroy); - container_output_destroy(output->swayc); + container_destroy(output->swayc); } static void handle_mode(struct wl_listener *listener, void *data) { diff --git a/sway/tree/container.c b/sway/tree/container.c index c1ebf4f1..1c41bf5d 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -109,6 +109,43 @@ struct sway_container *container_finish(struct sway_container *cont) { free(cont); 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) { + 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->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); + + wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); + container_finish(output); + return &root_container; +} + static struct sway_container *container_workspace_destroy( struct sway_container *workspace) { if (!sway_assert(workspace, "cannot destroy null workspace")) { diff --git a/sway/tree/output.c b/sway/tree/output.c index 0509db23..af17b856 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c @@ -4,42 +4,6 @@ #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->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); - - wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); - container_destroy(output); - return &root_container; -} - struct sway_container *output_by_name(const char *name) { for (int i = 0; i < root_container.children->length; ++i) { struct sway_container *output = root_container.children->items[i]; From cba258e16ac4d37841b89f2b6a38e1056acae97b Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 12:39:03 -0400 Subject: [PATCH 08/21] move output code out of the tree --- sway/desktop/output.c | 11 +++++++++++ sway/meson.build | 1 - sway/tree/output.c | 15 --------------- 3 files changed, 11 insertions(+), 16 deletions(-) delete mode 100644 sway/tree/output.c diff --git a/sway/desktop/output.c b/sway/desktop/output.c index a1f89cf9..e60fac5f 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -21,6 +22,16 @@ #include "sway/tree/layout.h" #include "sway/tree/view.h" +struct sway_container *output_by_name(const char *name) { + for (int i = 0; i < root_container.children->length; ++i) { + struct sway_container *output = root_container.children->items[i]; + if (strcasecmp(output->name, name) == 0){ + return output; + } + } + return NULL; +} + /** * Rotate a child's position relative to a parent. The parent size is (pw, ph), * the child position is (*sx, *sy) and its size is (sw, sh). diff --git a/sway/meson.build b/sway/meson.build index a6a633a0..87d882d2 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -86,7 +86,6 @@ sway_sources = files( 'security.c', 'tree/container.c', 'tree/layout.c', - 'tree/output.c', 'tree/view.c', 'tree/workspace.c', ) diff --git a/sway/tree/output.c b/sway/tree/output.c deleted file mode 100644 index af17b856..00000000 --- a/sway/tree/output.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include "sway/tree/container.h" -#include "sway/tree/layout.h" -#include "sway/output.h" -#include "log.h" - -struct sway_container *output_by_name(const char *name) { - for (int i = 0; i < root_container.children->length; ++i) { - struct sway_container *output = root_container.children->items[i]; - if (strcasecmp(output->name, name) == 0){ - return output; - } - } - return NULL; -} From 5f4761c4f40f5d6ec550ccabaebe0f990b6e8bbc Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 13:08:45 -0400 Subject: [PATCH 09/21] unify workspace create functions --- include/sway/tree/workspace.h | 2 -- sway/commands/move.c | 2 +- sway/commands/workspace.c | 6 ++--- sway/tree/container.c | 47 +++++++++++++++++++++++++++++------ sway/tree/workspace.c | 33 +++--------------------- 5 files changed, 46 insertions(+), 44 deletions(-) diff --git a/include/sway/tree/workspace.h b/include/sway/tree/workspace.h index 4e4c3450..8d49fefb 100644 --- a/include/sway/tree/workspace.h +++ b/include/sway/tree/workspace.h @@ -7,8 +7,6 @@ extern char *prev_workspace_name; char *workspace_next_name(const char *output_name); -struct sway_container *workspace_create(const char *name); - bool workspace_switch(struct sway_container *workspace); struct sway_container *workspace_by_number(const char* name); diff --git a/sway/commands/move.c b/sway/commands/move.c index 644c622b..7ac5f009 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c @@ -74,7 +74,7 @@ static struct cmd_results *cmd_move_container(struct sway_container *current, ws = workspace_by_name(ws_name); } if (!ws) { - ws = workspace_create(ws_name ? ws_name : num_name); + ws = container_workspace_create(NULL, ws_name ? ws_name : num_name); } free(ws_name); struct sway_container *old_parent = current->parent; diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index aa4096f7..a3702803 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c @@ -61,7 +61,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { if (strcasecmp(argv[0], "number") == 0) { if (!(ws = workspace_by_number(argv[1]))) { char *name = join_args(argv + 1, argc - 1); - ws = workspace_create(name); + ws = container_workspace_create(NULL, name); free(name); } } else if (strcasecmp(argv[0], "next") == 0) { @@ -80,12 +80,12 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { ws = old_workspace; } else if (prev_workspace_name && !(ws = workspace_by_name(prev_workspace_name))) { - ws = workspace_create(prev_workspace_name); + ws = container_workspace_create(NULL, prev_workspace_name); } } else { char *name = join_args(argv, argc); if (!(ws = workspace_by_name(name))) { - ws = workspace_create(name); + ws = container_workspace_create(NULL, name); } free(name); } diff --git a/sway/tree/container.c b/sway/tree/container.c index 1c41bf5d..7ccd43ea 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -110,7 +110,8 @@ struct sway_container *container_finish(struct sway_container *cont) { return parent; } -static struct sway_container *container_output_destroy(struct sway_container *output) { +static struct sway_container *container_output_destroy( + struct sway_container *output) { if (!sway_assert(output, "cannot destroy null output")) { return NULL; } @@ -245,7 +246,8 @@ struct sway_container *container_destroy(struct sway_container *con) { break; case C_CONTAINER: if (con->children != NULL && con->children->length) { - assert(false && "dont destroy container containers with children"); + assert(false && + "dont destroy container containers with children"); } container_finish(con); // TODO return parent to arrange maybe? @@ -271,7 +273,8 @@ static void container_close_func(struct sway_container *container, void *data) { } struct sway_container *container_close(struct sway_container *con) { - if (!sway_assert(con != NULL, "container_close called with a NULL container")) { + if (!sway_assert(con != NULL, + "container_close called with a NULL container")) { return NULL; } @@ -359,12 +362,39 @@ struct sway_container *container_output_create( return output; } -struct sway_container *container_workspace_create( - struct sway_container *output, const char *name) { - if (!sway_assert(output, - "container_workspace_create called with null output")) { - return NULL; +static struct sway_container *workspace_get_initial_output(const char *name) { + struct sway_container *parent; + // Search for workspace<->output pair + int i, e = config->workspace_outputs->length; + for (i = 0; i < e; ++i) { + struct workspace_output *wso = config->workspace_outputs->items[i]; + if (strcasecmp(wso->workspace, name) == 0) { + // Find output to use if it exists + e = root_container.children->length; + for (i = 0; i < e; ++i) { + parent = root_container.children->items[i]; + if (strcmp(parent->name, wso->output) == 0) { + return parent; + } + } + break; + } } + // Otherwise put it on the focused output + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = + seat_get_focus_inactive(seat, &root_container); + parent = focus; + parent = container_parent(parent, C_OUTPUT); + return parent; +} + +struct sway_container *container_workspace_create(struct sway_container *output, + const char *name) { + if (output == NULL) { + output = workspace_get_initial_output(name); + } + wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); struct sway_container *workspace = container_create(C_WORKSPACE); @@ -380,6 +410,7 @@ struct sway_container *container_workspace_create( container_add_child(output, workspace); container_sort_workspaces(output); notify_new_container(workspace); + return workspace; } diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 7d180009..d5a16410 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -179,35 +179,6 @@ struct sway_container *workspace_by_name(const char *name) { } } -struct sway_container *workspace_create(const char *name) { - struct sway_container *parent; - // Search for workspace<->output pair - int i, e = config->workspace_outputs->length; - for (i = 0; i < e; ++i) { - struct workspace_output *wso = config->workspace_outputs->items[i]; - if (strcasecmp(wso->workspace, name) == 0) { - // Find output to use if it exists - e = root_container.children->length; - for (i = 0; i < e; ++i) { - parent = root_container.children->items[i]; - if (strcmp(parent->name, wso->output) == 0) { - return container_workspace_create(parent, name); - } - } - break; - } - } - // Otherwise create a new one - struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = - seat_get_focus_inactive(seat, &root_container); - parent = focus; - parent = container_parent(parent, C_OUTPUT); - struct sway_container *new_ws = container_workspace_create(parent, name); - ipc_event_workspace(NULL, new_ws, "init"); - return new_ws; -} - /** * Get the previous or next workspace on the specified output. Wraps around at * the end and beginning. If next is false, the previous workspace is returned, @@ -319,7 +290,9 @@ bool workspace_switch(struct sway_container *workspace) { && active_ws == workspace && prev_workspace_name) { struct sway_container *new_ws = workspace_by_name(prev_workspace_name); - workspace = new_ws ? new_ws : workspace_create(prev_workspace_name); + workspace = new_ws ? + new_ws : + container_workspace_create(NULL, prev_workspace_name); } if (!prev_workspace_name || (strcmp(prev_workspace_name, active_ws->name) From fcbcbf34adbcfbfc4107c5e0050639828265e122 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 13:10:51 -0400 Subject: [PATCH 10/21] make container_finish private --- include/sway/tree/container.h | 3 --- sway/tree/container.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index c6393dc0..88ca67e9 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -130,9 +130,6 @@ struct sway_container *container_view_create( // TODO don't return the parent on destroy struct sway_container *container_destroy(struct sway_container *container); -// TODO make me private -struct sway_container *container_finish(struct sway_container *cont); - struct sway_container *container_close(struct sway_container *container); // TODO move to layout.c diff --git a/sway/tree/container.c b/sway/tree/container.c index 7ccd43ea..7cc8caa6 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -77,7 +77,7 @@ struct sway_container *container_create(enum sway_container_type type) { return c; } -struct sway_container *container_finish(struct sway_container *cont) { +static struct sway_container *container_finish(struct sway_container *cont) { if (cont == NULL) { return NULL; } From 065887bb7b25c1cf7d39459c79387a24e600085f Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 13:16:23 -0400 Subject: [PATCH 11/21] move container_set_layout to layout.h --- include/sway/tree/container.h | 4 ---- include/sway/tree/layout.h | 5 ++++- sway/tree/container.c | 13 ------------- sway/tree/layout.c | 13 +++++++++++++ 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 88ca67e9..23014dbe 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -132,10 +132,6 @@ struct sway_container *container_destroy(struct sway_container *container); struct sway_container *container_close(struct sway_container *container); -// TODO move to layout.c -struct sway_container *container_set_layout(struct sway_container *container, - enum sway_container_layout layout); - // TODO rename to container_descendants_for_each() void container_descendants(struct sway_container *root, enum sway_container_type type, diff --git a/include/sway/tree/layout.h b/include/sway/tree/layout.h index 9d33d561..725422c6 100644 --- a/include/sway/tree/layout.h +++ b/include/sway/tree/layout.h @@ -41,10 +41,13 @@ struct sway_container *container_add_sibling(struct sway_container *parent, struct sway_container *container_remove_child(struct sway_container *child); // TODO PRIVATE in tree.h - struct sway_container *container_replace_child(struct sway_container *child, struct sway_container *new_child); +// TODO move to layout.c +struct sway_container *container_set_layout(struct sway_container *container, + enum sway_container_layout layout); + // TODO move to tree.h void container_move_to(struct sway_container* container, struct sway_container* destination); diff --git a/sway/tree/container.c b/sway/tree/container.c index 7cc8caa6..a79bc22c 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -441,19 +441,6 @@ struct sway_container *container_view_create(struct sway_container *sibling, return swayc; } -struct sway_container *container_set_layout(struct sway_container *container, - enum sway_container_layout layout) { - if (container->type == C_WORKSPACE) { - container->workspace_layout = layout; - if (layout == L_HORIZ || layout == L_VERT) { - container->layout = layout; - } - } else { - container->layout = layout; - } - return container; -} - void container_descendants(struct sway_container *root, enum sway_container_type type, void (*func)(struct sway_container *item, void *data), void *data) { diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 487f895f..dfcdbb9c 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -47,6 +47,19 @@ static void output_layout_change_notify(struct wl_listener *listener, arrange_windows(&root_container, -1, -1); } +struct sway_container *container_set_layout(struct sway_container *container, + enum sway_container_layout layout) { + if (container->type == C_WORKSPACE) { + container->workspace_layout = layout; + if (layout == L_HORIZ || layout == L_VERT) { + container->layout = layout; + } + } else { + container->layout = layout; + } + return container; +} + void layout_init(void) { root_container.id = 0; // normally assigned in new_swayc() root_container.type = C_ROOT; From 9b567fc37e83ed9f0cbb028fd801a2f2609c79dc Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 13:23:34 -0400 Subject: [PATCH 12/21] clean up container_get_default_layout --- include/sway/tree/layout.h | 3 +-- sway/commands/layout.c | 3 +-- sway/tree/container.c | 2 +- sway/tree/layout.c | 14 ++++++++++++-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/include/sway/tree/layout.h b/include/sway/tree/layout.h index 725422c6..12689375 100644 --- a/include/sway/tree/layout.h +++ b/include/sway/tree/layout.h @@ -55,9 +55,8 @@ void container_move_to(struct sway_container* container, void container_move(struct sway_container *container, enum movement_direction dir, int move_amt); -// TODO move to output.c enum sway_container_layout container_get_default_layout( - struct sway_container *output); + struct sway_container *con); // TODO move to output.c void container_sort_workspaces(struct sway_container *output); diff --git a/sway/commands/layout.c b/sway/commands/layout.c index ebab2a48..4c49a627 100644 --- a/sway/commands/layout.c +++ b/sway/commands/layout.c @@ -28,8 +28,7 @@ struct cmd_results *cmd_layout(int argc, char **argv) { if (strcasecmp(argv[0], "default") == 0) { container_set_layout(parent, parent->prev_layout); if (parent->layout == L_NONE) { - struct sway_container *output = container_parent(parent, C_OUTPUT); - container_set_layout(parent, container_get_default_layout(output)); + container_set_layout(parent, container_get_default_layout(parent)); } } else { if (parent->layout != L_TABBED && parent->layout != L_STACKED) { diff --git a/sway/tree/container.c b/sway/tree/container.c index a79bc22c..64b51db6 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -405,7 +405,7 @@ struct sway_container *container_workspace_create(struct sway_container *output, workspace->name = !name ? NULL : strdup(name); workspace->prev_layout = L_NONE; workspace->layout = container_get_default_layout(output); - workspace->workspace_layout = container_get_default_layout(output); + workspace->workspace_layout = workspace->layout; container_add_child(output, workspace); container_sort_workspaces(output); diff --git a/sway/tree/layout.c b/sway/tree/layout.c index dfcdbb9c..c3cdaae0 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -168,12 +168,22 @@ void container_move(struct sway_container *container, } enum sway_container_layout container_get_default_layout( - struct sway_container *output) { + struct sway_container *con) { + if (con->type != C_OUTPUT) { + con = container_parent(con, C_OUTPUT); + } + + if (!sway_assert(con != NULL, + "container_get_default_layout must be called on an attached " + " container below the root container")) { + return 0; + } + if (config->default_layout != L_NONE) { return config->default_layout; } else if (config->default_orientation != L_NONE) { return config->default_orientation; - } else if (output->width >= output->height) { + } else if (con->width >= con->height) { return L_HORIZ; } else { return L_VERT; From a514fee1b9ac5a3538d8605ff358593cd53e73a8 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 13:24:48 -0400 Subject: [PATCH 13/21] rename workspace_get_initial_output --- sway/tree/container.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sway/tree/container.c b/sway/tree/container.c index 64b51db6..f616af09 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -362,7 +362,7 @@ struct sway_container *container_output_create( return output; } -static struct sway_container *workspace_get_initial_output(const char *name) { +static struct sway_container *get_workspace_initial_output(const char *name) { struct sway_container *parent; // Search for workspace<->output pair int i, e = config->workspace_outputs->length; @@ -392,7 +392,7 @@ static struct sway_container *workspace_get_initial_output(const char *name) { struct sway_container *container_workspace_create(struct sway_container *output, const char *name) { if (output == NULL) { - output = workspace_get_initial_output(name); + output = get_workspace_initial_output(name); } wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); From eca4468c2cacd87677f7f5831d8a74f8d811d318 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 17:06:57 -0400 Subject: [PATCH 14/21] fix old todos --- include/sway/tree/container.h | 6 ------ include/sway/tree/layout.h | 9 --------- 2 files changed, 15 deletions(-) diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index 23014dbe..f36b4bd1 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -91,12 +91,10 @@ struct sway_container { } events; }; -// TODO make private and use the container-specific create functions struct sway_container *container_create(enum sway_container_type type); const char *container_type_to_str(enum sway_container_type type); -// TODO only one container create function and pass the type? struct sway_container *container_output_create( struct sway_output *sway_output); @@ -123,16 +121,13 @@ struct sway_container *container_workspace_create(struct sway_container *output, * or a container container and are rendered in the order and structure of * how they are attached to the tree. */ -// TODO view containers should be created in a detached state. struct sway_container *container_view_create( struct sway_container *sibling, struct sway_view *sway_view); -// TODO don't return the parent on destroy struct sway_container *container_destroy(struct sway_container *container); struct sway_container *container_close(struct sway_container *container); -// TODO rename to container_descendants_for_each() void container_descendants(struct sway_container *root, enum sway_container_type type, void (*func)(struct sway_container *item, void *data), void *data); @@ -147,7 +142,6 @@ struct sway_container *container_find(struct sway_container *container, /** * Finds a parent container with the given struct sway_containerype. */ -// TODO rename to container_parent_of_type() struct sway_container *container_parent(struct sway_container *container, enum sway_container_type type); diff --git a/include/sway/tree/layout.h b/include/sway/tree/layout.h index 12689375..784dcc9b 100644 --- a/include/sway/tree/layout.h +++ b/include/sway/tree/layout.h @@ -29,26 +29,20 @@ struct sway_root { void layout_init(void); -// TODO move to tree.h void container_add_child(struct sway_container *parent, struct sway_container *child); -// TODO move to tree.h struct sway_container *container_add_sibling(struct sway_container *parent, struct sway_container *child); -// TODO move to tree.h struct sway_container *container_remove_child(struct sway_container *child); -// TODO PRIVATE in tree.h struct sway_container *container_replace_child(struct sway_container *child, struct sway_container *new_child); -// TODO move to layout.c struct sway_container *container_set_layout(struct sway_container *container, enum sway_container_layout layout); -// TODO move to tree.h void container_move_to(struct sway_container* container, struct sway_container* destination); @@ -58,17 +52,14 @@ void container_move(struct sway_container *container, enum sway_container_layout container_get_default_layout( struct sway_container *con); -// TODO move to output.c void container_sort_workspaces(struct sway_container *output); void arrange_windows(struct sway_container *container, double width, double height); -// TODO move to container.h struct sway_container *container_get_in_direction(struct sway_container *container, struct sway_seat *seat, enum movement_direction dir); -// TODO move to tree.h struct sway_container *container_split(struct sway_container *child, enum sway_container_layout layout); From 481a8275c178f81bb2d9927c5047e959fdbc383a Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 19:23:59 -0400 Subject: [PATCH 15/21] address feedback --- sway/commands/kill.c | 14 +---- sway/desktop/output.c | 2 +- sway/tree/container.c | 135 +++++++++++++++++++++++------------------- sway/tree/layout.c | 2 +- sway/tree/view.c | 4 +- 5 files changed, 79 insertions(+), 78 deletions(-) diff --git a/sway/commands/kill.c b/sway/commands/kill.c index 811c3e6b..f3fa52f1 100644 --- a/sway/commands/kill.c +++ b/sway/commands/kill.c @@ -10,19 +10,7 @@ struct cmd_results *cmd_kill(int argc, char **argv) { struct sway_container *con = config->handler_context.current_container; - switch (con->type) { - case C_ROOT: - case C_OUTPUT: - case C_WORKSPACE: - case C_TYPES: - return cmd_results_new(CMD_INVALID, NULL, - "Can only kill views and containers with this command"); - break; - case C_CONTAINER: - case C_VIEW: - container_close(con); - break; - } + container_close(con); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/desktop/output.c b/sway/desktop/output.c index e60fac5f..de5076d8 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -25,7 +25,7 @@ struct sway_container *output_by_name(const char *name) { for (int i = 0; i < root_container.children->length; ++i) { struct sway_container *output = root_container.children->items[i]; - if (strcasecmp(output->name, name) == 0){ + if (strcasecmp(output->name, name) == 0) { return output; } } diff --git a/sway/tree/container.c b/sway/tree/container.c index f616af09..77c61b3f 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -186,84 +186,97 @@ static struct sway_container *container_workspace_destroy( return parent; } - -static void reap_empty_func(struct sway_container *con, void *data) { - switch (con->type) { - case C_TYPES: - case C_ROOT: - case C_OUTPUT: - // dont reap these - break; - case C_WORKSPACE: - if (!workspace_is_visible(con) && con->children->length == 0) { - container_workspace_destroy(con); - } - break; - case C_CONTAINER: - if (con->children->length == 0) { - container_finish(con); - } else if (con->children->length == 1) { - struct sway_container *only_child = con->children->items[0]; - if (only_child->type == C_CONTAINER) { - container_remove_child(only_child); - container_replace_child(con, only_child); - container_finish(con); - } - } - case C_VIEW: - break; - } -} - -struct sway_container *container_reap_empty(struct sway_container *container) { - struct sway_container *parent = container->parent; - - container_for_each_descendant_dfs(container, reap_empty_func, NULL); - - return parent; -} - static void container_root_finish(struct sway_container *con) { wlr_log(L_ERROR, "TODO: destroy the root container"); } +static bool container_reap_empty(struct sway_container *con) { + switch (con->type) { + case C_ROOT: + case C_OUTPUT: + // dont reap these + break; + case C_WORKSPACE: + if (!workspace_is_visible(con) && con->children->length == 0) { + container_workspace_destroy(con); + return true; + } + break; + case C_CONTAINER: + if (con->children->length == 0) { + container_finish(con); + return true; + } else if (con->children->length == 1) { + struct sway_container *child = con->children->items[0]; + if (child->type == C_CONTAINER) { + container_remove_child(child); + container_replace_child(con, child); + container_finish(con); + return true; + } + } + case C_VIEW: + break; + case C_TYPES: + sway_assert(false, "container_reap_empty called on an invalid " + "container"); + break; + } + + return false; +} + struct sway_container *container_destroy(struct sway_container *con) { if (con == NULL) { return NULL; } - struct sway_container *anscestor = NULL; + struct sway_container *parent = con->parent; switch (con->type) { case C_ROOT: container_root_finish(con); break; case C_OUTPUT: - anscestor = container_output_destroy(con); + // dont try to reap the root after this + container_output_destroy(con); break; case C_WORKSPACE: - anscestor = container_workspace_destroy(con); + // dont try to reap the output after this + container_workspace_destroy(con); break; case C_CONTAINER: - if (con->children != NULL && con->children->length) { - assert(false && - "dont destroy container containers with children"); + if (con->children->length) { + for (int i = 0; i < con->children->length; ++i) { + struct sway_container *child = con->children->items[0]; + container_remove_child(child); + container_add_child(parent, child); + } + container_finish(con); } container_finish(con); - // TODO return parent to arrange maybe? break; case C_VIEW: container_finish(con); - // TODO return parent to arrange maybe? break; case C_TYPES: - wlr_log(L_ERROR, "tried to destroy an invalid container"); + wlr_log(L_ERROR, "container_destroy called on an invalid " + "container"); break; } - container_reap_empty(&root_container); + struct sway_container *tmp = parent; + while (parent) { + tmp = parent->parent; - return anscestor; + if (!container_reap_empty(parent)) { + break; + } + + parent = tmp; + } + + return tmp; } static void container_close_func(struct sway_container *container, void *data) { @@ -274,23 +287,23 @@ static void container_close_func(struct sway_container *container, void *data) { struct sway_container *container_close(struct sway_container *con) { if (!sway_assert(con != NULL, - "container_close called with a NULL container")) { + "container_close called with a NULL container")) { return NULL; } struct sway_container *parent = con->parent; switch (con->type) { - case C_TYPES: - case C_ROOT: - case C_OUTPUT: - case C_WORKSPACE: - case C_CONTAINER: - container_for_each_descendant_dfs(con, container_close_func, NULL); - break; - case C_VIEW: - view_close(con->sway_view); - break; + case C_TYPES: + case C_ROOT: + case C_OUTPUT: + case C_WORKSPACE: + case C_CONTAINER: + container_for_each_descendant_dfs(con, container_close_func, NULL); + break; + case C_VIEW: + view_close(con->sway_view); + break; } @@ -365,8 +378,8 @@ struct sway_container *container_output_create( static struct sway_container *get_workspace_initial_output(const char *name) { struct sway_container *parent; // Search for workspace<->output pair - int i, e = config->workspace_outputs->length; - for (i = 0; i < e; ++i) { + int e = config->workspace_outputs->length; + for (int i = 0; i < config->workspace_outputs->length; ++i) { struct workspace_output *wso = config->workspace_outputs->items[i]; if (strcasecmp(wso->workspace, name) == 0) { // Find output to use if it exists diff --git a/sway/tree/layout.c b/sway/tree/layout.c index c3cdaae0..3cbbf3b4 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -174,7 +174,7 @@ enum sway_container_layout container_get_default_layout( } if (!sway_assert(con != NULL, - "container_get_default_layout must be called on an attached " + "container_get_default_layout must be called on an attached" " container below the root container")) { return 0; } diff --git a/sway/tree/view.c b/sway/tree/view.c index c06924f5..aa010a40 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -149,12 +149,12 @@ void view_unmap(struct sway_view *view) { view_damage_whole(view); - container_destroy(view->swayc); + struct sway_container *parent = container_destroy(view->swayc); view->swayc = NULL; view->surface = NULL; - arrange_windows(&root_container, -1, -1); + arrange_windows(parent, -1, -1); } void view_update_position(struct sway_view *view, double ox, double oy) { From 035a88e0dc325e8225478632b3d4b02a72fcf29a Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 19:32:09 -0400 Subject: [PATCH 16/21] rename container_finish to _container_destroy --- sway/tree/container.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/sway/tree/container.c b/sway/tree/container.c index 77c61b3f..2fd03067 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -77,21 +77,21 @@ struct sway_container *container_create(enum sway_container_type type) { return c; } -static struct sway_container *container_finish(struct sway_container *cont) { +static void _container_destroy(struct sway_container *cont) { if (cont == NULL) { - return NULL; + return; } wl_signal_emit(&cont->events.destroy, cont); struct sway_container *parent = cont->parent; - if (cont->children != NULL) { + if (cont->children != NULL && cont->children->length) { // remove children until there are no more, container_destroy calls // container_remove_child, which removes child from this container - while (cont->children != NULL && cont->children->length != 0) { + while (cont->children != NULL) { struct sway_container *child = cont->children->items[0]; container_remove_child(child); - container_finish(child); + _container_destroy(child); } } if (cont->marks) { @@ -107,7 +107,6 @@ static struct sway_container *container_finish(struct sway_container *cont) { list_free(cont->children); cont->children = NULL; free(cont); - return parent; } static struct sway_container *container_output_destroy( @@ -143,7 +142,7 @@ static struct sway_container *container_output_destroy( wl_list_remove(&output->sway_output->damage_frame.link); wlr_log(L_DEBUG, "OUTPUT: Destroying output '%s'", output->name); - container_finish(output); + _container_destroy(output); return &root_container; } @@ -182,7 +181,7 @@ static struct sway_container *container_workspace_destroy( } } - container_finish(workspace); + _container_destroy(workspace); return parent; } @@ -204,14 +203,14 @@ static bool container_reap_empty(struct sway_container *con) { break; case C_CONTAINER: if (con->children->length == 0) { - container_finish(con); + _container_destroy(con); return true; } else if (con->children->length == 1) { struct sway_container *child = con->children->items[0]; if (child->type == C_CONTAINER) { container_remove_child(child); container_replace_child(con, child); - container_finish(con); + _container_destroy(con); return true; } } @@ -252,12 +251,12 @@ struct sway_container *container_destroy(struct sway_container *con) { container_remove_child(child); container_add_child(parent, child); } - container_finish(con); + _container_destroy(con); } - container_finish(con); + _container_destroy(con); break; case C_VIEW: - container_finish(con); + _container_destroy(con); break; case C_TYPES: wlr_log(L_ERROR, "container_destroy called on an invalid " From 97b171649dd0f387ecd471dc75feda6307e7dbe3 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 19:36:57 -0400 Subject: [PATCH 17/21] move output damage to workspace destructor --- sway/input/seat.c | 1 - sway/tree/container.c | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sway/input/seat.c b/sway/input/seat.c index d752acb8..c326f176 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -381,7 +381,6 @@ void seat_set_focus_warp(struct sway_seat *seat, if (last_ws) { ipc_event_workspace(last_ws, container, "focus"); if (last_ws->children->length == 0) { - output_damage_whole(last_ws->parent->sway_output); container_destroy(last_ws); } } diff --git a/sway/tree/container.c b/sway/tree/container.c index 2fd03067..fdbb2922 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -182,6 +182,9 @@ static struct sway_container *container_workspace_destroy( } _container_destroy(workspace); + + output_damage_whole(output->sway_output); + return parent; } From a001890fb8a9fc8c7f0b8eac03ca5912be2de479 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 19:52:17 -0400 Subject: [PATCH 18/21] move workspace create to workspace.c --- include/sway/tree/container.h | 8 +++-- sway/commands/move.c | 2 +- sway/commands/workspace.c | 6 ++-- sway/desktop/output.c | 2 +- sway/tree/container.c | 62 +++-------------------------------- sway/tree/layout.c | 2 +- sway/tree/workspace.c | 54 +++++++++++++++++++++++++++++- 7 files changed, 69 insertions(+), 67 deletions(-) diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index f36b4bd1..277165ea 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h @@ -95,7 +95,7 @@ struct sway_container *container_create(enum sway_container_type type); const char *container_type_to_str(enum sway_container_type type); -struct sway_container *container_output_create( +struct sway_container *output_create( struct sway_output *sway_output); /** @@ -108,13 +108,13 @@ struct sway_container *container_container_create(); * Create a new output. Outputs are children of the root container and have no * order in the tree structure. */ -struct sway_container *container_output_create(struct sway_output *sway_output); +struct sway_container *output_create(struct sway_output *sway_output); /** * Create a new workspace container. Workspaces are children of an output * container and are ordered alphabetically by name. */ -struct sway_container *container_workspace_create(struct sway_container *output, const char *name); +struct sway_container *workspace_create(struct sway_container *output, const char *name); /* * Create a new view container. A view can be a child of a workspace container @@ -178,4 +178,6 @@ bool container_has_anscestor(struct sway_container *container, bool container_has_child(struct sway_container *con, struct sway_container *child); +void container_create_notify(struct sway_container *container); + #endif diff --git a/sway/commands/move.c b/sway/commands/move.c index 7ac5f009..c954ab94 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c @@ -74,7 +74,7 @@ static struct cmd_results *cmd_move_container(struct sway_container *current, ws = workspace_by_name(ws_name); } if (!ws) { - ws = container_workspace_create(NULL, ws_name ? ws_name : num_name); + ws = workspace_create(NULL, ws_name ? ws_name : num_name); } free(ws_name); struct sway_container *old_parent = current->parent; diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index a3702803..958b3222 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c @@ -61,7 +61,7 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { if (strcasecmp(argv[0], "number") == 0) { if (!(ws = workspace_by_number(argv[1]))) { char *name = join_args(argv + 1, argc - 1); - ws = container_workspace_create(NULL, name); + ws = workspace_create(NULL, name); free(name); } } else if (strcasecmp(argv[0], "next") == 0) { @@ -80,12 +80,12 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { ws = old_workspace; } else if (prev_workspace_name && !(ws = workspace_by_name(prev_workspace_name))) { - ws = container_workspace_create(NULL, prev_workspace_name); + ws = workspace_create(NULL, prev_workspace_name); } } else { char *name = join_args(argv, argc); if (!(ws = workspace_by_name(name))) { - ws = container_workspace_create(NULL, name); + ws = workspace_create(NULL, name); } free(name); } diff --git a/sway/desktop/output.c b/sway/desktop/output.c index de5076d8..96f23291 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -396,7 +396,7 @@ void handle_new_output(struct wl_listener *listener, void *data) { output->damage = wlr_output_damage_create(wlr_output); - output->swayc = container_output_create(output); + output->swayc = output_create(output); if (!output->swayc) { free(output); return; diff --git a/sway/tree/container.c b/sway/tree/container.c index fdbb2922..8ed30b44 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -51,7 +51,7 @@ const char *container_type_to_str(enum sway_container_type type) { } } -static void notify_new_container(struct sway_container *container) { +void container_create_notify(struct sway_container *container) { wl_signal_emit(&root_container.sway_root->events.new_container, container); ipc_event_window(container, "new"); } @@ -312,7 +312,7 @@ struct sway_container *container_close(struct sway_container *con) { return parent; } -struct sway_container *container_output_create( +struct sway_container *output_create( struct sway_output *sway_output) { struct wlr_box size; wlr_output_effective_resolution(sway_output->wlr_output, &size.width, @@ -363,7 +363,7 @@ struct sway_container *container_output_create( // Create workspace char *ws_name = workspace_next_name(output->name); wlr_log(L_DEBUG, "Creating default workspace %s", ws_name); - struct sway_container *ws = container_workspace_create(output, ws_name); + struct sway_container *ws = workspace_create(output, ws_name); // Set each seat's focus if not already set struct sway_seat *seat = NULL; wl_list_for_each(seat, &input_manager->seats, link) { @@ -373,62 +373,10 @@ struct sway_container *container_output_create( } free(ws_name); - notify_new_container(output); + container_create_notify(output); return output; } -static struct sway_container *get_workspace_initial_output(const char *name) { - struct sway_container *parent; - // Search for workspace<->output pair - int e = config->workspace_outputs->length; - for (int i = 0; i < config->workspace_outputs->length; ++i) { - struct workspace_output *wso = config->workspace_outputs->items[i]; - if (strcasecmp(wso->workspace, name) == 0) { - // Find output to use if it exists - e = root_container.children->length; - for (i = 0; i < e; ++i) { - parent = root_container.children->items[i]; - if (strcmp(parent->name, wso->output) == 0) { - return parent; - } - } - break; - } - } - // Otherwise put it on the focused output - struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = - seat_get_focus_inactive(seat, &root_container); - parent = focus; - parent = container_parent(parent, C_OUTPUT); - return parent; -} - -struct sway_container *container_workspace_create(struct sway_container *output, - const char *name) { - if (output == NULL) { - output = get_workspace_initial_output(name); - } - - wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); - struct sway_container *workspace = container_create(C_WORKSPACE); - - workspace->x = output->x; - workspace->y = output->y; - workspace->width = output->width; - workspace->height = output->height; - workspace->name = !name ? NULL : strdup(name); - workspace->prev_layout = L_NONE; - workspace->layout = container_get_default_layout(output); - workspace->workspace_layout = workspace->layout; - - container_add_child(output, workspace); - container_sort_workspaces(output); - notify_new_container(workspace); - - return workspace; -} - struct sway_container *container_view_create(struct sway_container *sibling, struct sway_view *sway_view) { if (!sway_assert(sibling, @@ -452,7 +400,7 @@ struct sway_container *container_view_create(struct sway_container *sibling, // Regular case, create as sibling of current container container_add_sibling(sibling, swayc); } - notify_new_container(swayc); + container_create_notify(swayc); return swayc; } diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 3cbbf3b4..a46359bd 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c @@ -149,7 +149,7 @@ void container_move_to(struct sway_container *container, if (old_parent->children->length == 0) { char *ws_name = workspace_next_name(old_parent->name); struct sway_container *ws = - container_workspace_create(old_parent, ws_name); + workspace_create(old_parent, ws_name); free(ws_name); seat_set_focus(seat, ws); } diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index d5a16410..6ba3d973 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -14,6 +14,58 @@ #include "log.h" #include "util.h" +static struct sway_container *get_workspace_initial_output(const char *name) { + struct sway_container *parent; + // Search for workspace<->output pair + int e = config->workspace_outputs->length; + for (int i = 0; i < config->workspace_outputs->length; ++i) { + struct workspace_output *wso = config->workspace_outputs->items[i]; + if (strcasecmp(wso->workspace, name) == 0) { + // Find output to use if it exists + e = root_container.children->length; + for (i = 0; i < e; ++i) { + parent = root_container.children->items[i]; + if (strcmp(parent->name, wso->output) == 0) { + return parent; + } + } + break; + } + } + // Otherwise put it on the focused output + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = + seat_get_focus_inactive(seat, &root_container); + parent = focus; + parent = container_parent(parent, C_OUTPUT); + return parent; +} + +struct sway_container *workspace_create(struct sway_container *output, + const char *name) { + if (output == NULL) { + output = get_workspace_initial_output(name); + } + + wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); + struct sway_container *workspace = container_create(C_WORKSPACE); + + workspace->x = output->x; + workspace->y = output->y; + workspace->width = output->width; + workspace->height = output->height; + workspace->name = !name ? NULL : strdup(name); + workspace->prev_layout = L_NONE; + workspace->layout = container_get_default_layout(output); + workspace->workspace_layout = workspace->layout; + + container_add_child(output, workspace); + container_sort_workspaces(output); + container_create_notify(workspace); + + return workspace; +} + char *prev_workspace_name = NULL; struct workspace_by_number_data { int len; @@ -292,7 +344,7 @@ bool workspace_switch(struct sway_container *workspace) { struct sway_container *new_ws = workspace_by_name(prev_workspace_name); workspace = new_ws ? new_ws : - container_workspace_create(NULL, prev_workspace_name); + workspace_create(NULL, prev_workspace_name); } if (!prev_workspace_name || (strcmp(prev_workspace_name, active_ws->name) From fa004dd0d78b922b75a6cc9c970824d18aa4e4aa Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 20:00:09 -0400 Subject: [PATCH 19/21] move output create to its own file --- include/sway/tree/output.h | 0 sway/meson.build | 1 + sway/tree/container.c | 66 ---------------------------------- sway/tree/output.c | 73 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 66 deletions(-) create mode 100644 include/sway/tree/output.h create mode 100644 sway/tree/output.c diff --git a/include/sway/tree/output.h b/include/sway/tree/output.h new file mode 100644 index 00000000..e69de29b diff --git a/sway/meson.build b/sway/meson.build index 87d882d2..91aab0a0 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -88,6 +88,7 @@ sway_sources = files( 'tree/layout.c', 'tree/view.c', 'tree/workspace.c', + 'tree/output.c', ) sway_deps = [ diff --git a/sway/tree/container.c b/sway/tree/container.c index 8ed30b44..7f55ad90 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -7,7 +7,6 @@ #include #include #include -#include "log.h" #include "sway/config.h" #include "sway/input/input-manager.h" #include "sway/input/seat.h" @@ -312,71 +311,6 @@ struct sway_container *container_close(struct sway_container *con) { return parent; } -struct sway_container *output_create( - struct sway_output *sway_output) { - struct wlr_box size; - wlr_output_effective_resolution(sway_output->wlr_output, &size.width, - &size.height); - - const char *name = sway_output->wlr_output->name; - char identifier[128]; - output_get_identifier(identifier, sizeof(identifier), sway_output); - - struct output_config *oc = NULL, *all = NULL; - for (int i = 0; i < config->output_configs->length; ++i) { - struct output_config *cur = config->output_configs->items[i]; - - if (strcasecmp(name, cur->name) == 0 || - strcasecmp(identifier, cur->name) == 0) { - wlr_log(L_DEBUG, "Matched output config for %s", name); - oc = cur; - } - if (strcasecmp("*", cur->name) == 0) { - wlr_log(L_DEBUG, "Matched wildcard output config for %s", name); - all = cur; - } - - if (oc && all) { - break; - } - } - if (!oc) { - oc = all; - } - - if (oc && !oc->enabled) { - return NULL; - } - - struct sway_container *output = container_create(C_OUTPUT); - output->sway_output = sway_output; - output->name = strdup(name); - if (output->name == NULL) { - container_destroy(output); - return NULL; - } - - apply_output_config(oc, output); - container_add_child(&root_container, output); - load_swaybars(); - - // Create workspace - char *ws_name = workspace_next_name(output->name); - wlr_log(L_DEBUG, "Creating default workspace %s", ws_name); - struct sway_container *ws = workspace_create(output, ws_name); - // Set each seat's focus if not already set - struct sway_seat *seat = NULL; - wl_list_for_each(seat, &input_manager->seats, link) { - if (!seat->has_focus) { - seat_set_focus(seat, ws); - } - } - - free(ws_name); - container_create_notify(output); - return output; -} - struct sway_container *container_view_create(struct sway_container *sibling, struct sway_view *sway_view) { if (!sway_assert(sibling, diff --git a/sway/tree/output.c b/sway/tree/output.c new file mode 100644 index 00000000..6c7044a2 --- /dev/null +++ b/sway/tree/output.c @@ -0,0 +1,73 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include "sway/output.h" +#include "sway/tree/output.h" +#include "sway/tree/workspace.h" +#include "log.h" + +struct sway_container *output_create( + struct sway_output *sway_output) { + struct wlr_box size; + wlr_output_effective_resolution(sway_output->wlr_output, &size.width, + &size.height); + + const char *name = sway_output->wlr_output->name; + char identifier[128]; + output_get_identifier(identifier, sizeof(identifier), sway_output); + + struct output_config *oc = NULL, *all = NULL; + for (int i = 0; i < config->output_configs->length; ++i) { + struct output_config *cur = config->output_configs->items[i]; + + if (strcasecmp(name, cur->name) == 0 || + strcasecmp(identifier, cur->name) == 0) { + wlr_log(L_DEBUG, "Matched output config for %s", name); + oc = cur; + } + if (strcasecmp("*", cur->name) == 0) { + wlr_log(L_DEBUG, "Matched wildcard output config for %s", name); + all = cur; + } + + if (oc && all) { + break; + } + } + if (!oc) { + oc = all; + } + + if (oc && !oc->enabled) { + return NULL; + } + + struct sway_container *output = container_create(C_OUTPUT); + output->sway_output = sway_output; + output->name = strdup(name); + if (output->name == NULL) { + container_destroy(output); + return NULL; + } + + apply_output_config(oc, output); + container_add_child(&root_container, output); + load_swaybars(); + + // Create workspace + char *ws_name = workspace_next_name(output->name); + wlr_log(L_DEBUG, "Creating default workspace %s", ws_name); + struct sway_container *ws = workspace_create(output, ws_name); + // Set each seat's focus if not already set + struct sway_seat *seat = NULL; + wl_list_for_each(seat, &input_manager->seats, link) { + if (!seat->has_focus) { + seat_set_focus(seat, ws); + } + } + + free(ws_name); + container_create_notify(output); + return output; +} + From 9d1cbd77aca72ca72eaba5056de5805b14f004c1 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 23:59:44 -0400 Subject: [PATCH 20/21] simplify container close --- sway/tree/container.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/sway/tree/container.c b/sway/tree/container.c index 7f55ad90..57dcb4bd 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -294,18 +294,10 @@ struct sway_container *container_close(struct sway_container *con) { struct sway_container *parent = con->parent; - switch (con->type) { - case C_TYPES: - case C_ROOT: - case C_OUTPUT: - case C_WORKSPACE: - case C_CONTAINER: - container_for_each_descendant_dfs(con, container_close_func, NULL); - break; - case C_VIEW: + if (con->type == C_VIEW) { view_close(con->sway_view); - break; - + } else { + container_for_each_descendant_dfs(con, container_close_func, NULL); } return parent; From 62c79ef4510d4687e35deab177cf5114a138261f Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Wed, 4 Apr 2018 00:22:40 -0400 Subject: [PATCH 21/21] fix double free --- sway/tree/container.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sway/tree/container.c b/sway/tree/container.c index 57dcb4bd..eaf4c117 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -253,7 +253,6 @@ struct sway_container *container_destroy(struct sway_container *con) { container_remove_child(child); container_add_child(parent, child); } - _container_destroy(con); } _container_destroy(con); break;