From 2c165e1288cbb60f5e677595e35f58a9c56c7010 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 2 Apr 2018 21:01:33 -0400 Subject: fix more close segfaults --- sway/tree/view.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/tree/view.c') 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; } -- cgit v1.2.3 From 2992b72d61933568476e2bf4baf573e714f9ed40 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Mon, 2 Apr 2018 22:37:21 -0400 Subject: 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(-) (limited to 'sway/tree/view.c') 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) { -- cgit v1.2.3 From b4c5f79725142c78a398a22981392d645bc9d2e9 Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 12:25:19 -0400 Subject: 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(-) (limited to 'sway/tree/view.c') 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, -- cgit v1.2.3 From 481a8275c178f81bb2d9927c5047e959fdbc383a Mon Sep 17 00:00:00 2001 From: Tony Crisci Date: Tue, 3 Apr 2018 19:23:59 -0400 Subject: address feedback --- sway/commands/kill.c | 14 +----- sway/desktop/output.c | 2 +- sway/tree/container.c | 127 ++++++++++++++++++++++++++++---------------------- sway/tree/layout.c | 2 +- sway/tree/view.c | 4 +- 5 files changed, 75 insertions(+), 74 deletions(-) (limited to 'sway/tree/view.c') 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,45 +186,44 @@ static struct sway_container *container_workspace_destroy( return parent; } +static void container_root_finish(struct sway_container *con) { + wlr_log(L_ERROR, "TODO: destroy the root container"); +} -static void reap_empty_func(struct sway_container *con, void *data) { +static bool container_reap_empty(struct sway_container *con) { 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) { + 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); - } 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); - } + return true; } - case C_VIEW: - break; + } + case C_VIEW: + break; + case C_TYPES: + sway_assert(false, "container_reap_empty called on an invalid " + "container"); + 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"); + return false; } struct sway_container *container_destroy(struct sway_container *con) { @@ -232,38 +231,52 @@ struct sway_container *container_destroy(struct sway_container *con) { 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; + + if (!container_reap_empty(parent)) { + break; + } + + parent = tmp; + } - return anscestor; + 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) { -- cgit v1.2.3