diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-09-05 09:33:27 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-05 09:33:27 -0400 |
commit | 610eb946171f782165a20614b2d3318b89273990 (patch) | |
tree | 05eec1df1ef48e05b23d273d31143ad32e7632d2 /sway/tree/workspace.c | |
parent | aa2bf98e0442f9bf41a852c2fafee5b0897010a2 (diff) | |
parent | dbf4aa3e33bdee53876c6893b15ac3f224818e7c (diff) |
Merge pull request #2540 from RyanDwyer/typesafety
Implement type safe arguments and demote sway_container
Diffstat (limited to 'sway/tree/workspace.c')
-rw-r--r-- | sway/tree/workspace.c | 493 |
1 files changed, 238 insertions, 255 deletions
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 1957d94f..bb1ded22 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -12,128 +12,105 @@ #include "sway/output.h" #include "sway/tree/arrange.h" #include "sway/tree/container.h" +#include "sway/tree/node.h" #include "sway/tree/view.h" #include "sway/tree/workspace.h" #include "list.h" #include "log.h" #include "util.h" -struct sway_container *workspace_get_initial_output(const char *name) { - struct sway_container *parent; +struct sway_output *workspace_get_initial_output(const char *name) { // 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; - } + struct sway_output *output = output_by_name(wso->output); + if (output) { + return output; } 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_workspace *focus = seat_get_focused_workspace(seat); + return focus->output; } -struct sway_container *workspace_create(struct sway_container *output, +struct sway_workspace *workspace_create(struct sway_output *output, const char *name) { if (output == NULL) { output = workspace_get_initial_output(name); } - wlr_log(WLR_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_split_layout = L_NONE; - workspace->layout = container_get_default_layout(output); + wlr_log(WLR_DEBUG, "Adding workspace %s for output %s", name, + output->wlr_output->name); - struct sway_workspace *swayws = calloc(1, sizeof(struct sway_workspace)); - if (!swayws) { + struct sway_workspace *ws = calloc(1, sizeof(struct sway_workspace)); + if (!ws) { + wlr_log(WLR_ERROR, "Unable to allocate sway_workspace"); return NULL; } - swayws->swayc = workspace; - swayws->floating = create_list(); - swayws->output_priority = create_list(); - workspace->sway_workspace = swayws; - workspace_output_add_priority(workspace, output); - - container_add_child(output, workspace); + node_init(&ws->node, N_WORKSPACE, ws); + ws->x = output->lx; + ws->y = output->ly; + ws->width = output->width; + ws->height = output->height; + ws->name = name ? strdup(name) : NULL; + ws->prev_split_layout = L_NONE; + ws->layout = output_get_default_layout(output); + ws->floating = create_list(); + ws->tiling = create_list(); + ws->output_priority = create_list(); + workspace_output_add_priority(ws, output); + + output_add_workspace(output, ws); output_sort_workspaces(output); - container_create_notify(workspace); - return workspace; + ipc_event_workspace(NULL, ws, "init"); + wl_signal_emit(&root->events.new_node, &ws->node); + + return ws; } -void workspace_destroy(struct sway_container *workspace) { - if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { - return; - } - if (!sway_assert(workspace->destroying, +void workspace_destroy(struct sway_workspace *workspace) { + if (!sway_assert(workspace->node.destroying, "Tried to free workspace which wasn't marked as destroying")) { return; } - if (!sway_assert(workspace->ntxnrefs == 0, "Tried to free workspace " + if (!sway_assert(workspace->node.ntxnrefs == 0, "Tried to free workspace " "which is still referenced by transactions")) { return; } - // sway_workspace - struct sway_workspace *ws = workspace->sway_workspace; - list_foreach(ws->output_priority, free); - list_free(ws->output_priority); - list_free(ws->floating); - free(ws); - // swayc free(workspace->name); - free(workspace->formatted_title); - wlr_texture_destroy(workspace->title_focused); - wlr_texture_destroy(workspace->title_focused_inactive); - wlr_texture_destroy(workspace->title_unfocused); - wlr_texture_destroy(workspace->title_urgent); - list_free(workspace->children); - list_free(workspace->current.children); - list_free(workspace->outputs); + free(workspace->representation); + list_foreach(workspace->output_priority, free); + list_free(workspace->output_priority); + list_free(workspace->floating); + list_free(workspace->tiling); + list_free(workspace->current.floating); + list_free(workspace->current.tiling); free(workspace); } -void workspace_begin_destroy(struct sway_container *workspace) { - if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { - return; - } +void workspace_begin_destroy(struct sway_workspace *workspace) { wlr_log(WLR_DEBUG, "Destroying workspace '%s'", workspace->name); - wl_signal_emit(&workspace->events.destroy, workspace); ipc_event_workspace(NULL, workspace, "empty"); // intentional + wl_signal_emit(&workspace->node.events.destroy, &workspace->node); - workspace->destroying = true; - container_set_dirty(workspace); - - if (workspace->parent) { - container_remove_child(workspace); + if (workspace->output) { + workspace_detach(workspace); } + + workspace->node.destroying = true; + node_set_dirty(&workspace->node); } -void workspace_consider_destroy(struct sway_container *ws) { - if (!sway_assert(ws->type == C_WORKSPACE, "Expected a workspace")) { - return; - } - struct sway_seat *seat = input_manager_current_seat(input_manager); - if (ws->children->length == 0 && ws->sway_workspace->floating->length == 0 - && seat_get_active_child(seat, ws->parent) != ws) { +void workspace_consider_destroy(struct sway_workspace *ws) { + if (ws->tiling->length == 0 && ws->floating->length == 0 + && output_get_active_workspace(ws->output) != ws) { workspace_begin_destroy(ws); } } @@ -272,59 +249,49 @@ char *workspace_next_name(const char *output_name) { } // As a fall back, get the current number of active workspaces // and return that + 1 for the next workspace's name - int ws_num = root_container.children->length; + int ws_num = root->outputs->length; int l = snprintf(NULL, 0, "%d", ws_num); char *name = malloc(l + 1); - if (!sway_assert(name, "Cloud not allocate workspace name")) { + if (!sway_assert(name, "Could not allocate workspace name")) { return NULL; } sprintf(name, "%d", ws_num++); return name; } -static bool _workspace_by_number(struct sway_container *view, void *data) { - if (view->type != C_WORKSPACE) { - return false; - } +static bool _workspace_by_number(struct sway_workspace *ws, void *data) { char *name = data; - char *view_name = view->name; + char *ws_name = ws->name; while (isdigit(*name)) { - if (*name++ != *view_name++) { + if (*name++ != *ws_name++) { return false; } } - return !isdigit(*view_name); + return !isdigit(*ws_name); } -struct sway_container *workspace_by_number(const char* name) { +struct sway_workspace *workspace_by_number(const char* name) { return root_find_workspace(_workspace_by_number, (void *) name); } -static bool _workspace_by_name(struct sway_container *view, void *data) { - return (view->type == C_WORKSPACE) && - (strcasecmp(view->name, (char *) data) == 0); +static bool _workspace_by_name(struct sway_workspace *ws, void *data) { + return strcasecmp(ws->name, data) == 0; } -struct sway_container *workspace_by_name(const char *name) { +struct sway_workspace *workspace_by_name(const char *name) { struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *current_workspace = NULL, *current_output = NULL; - struct sway_container *focus = seat_get_focus(seat); - if (focus) { - current_workspace = focus->type == C_WORKSPACE ? - focus : container_parent(focus, C_WORKSPACE); - current_output = container_parent(focus, C_OUTPUT); - } + struct sway_workspace *current = seat_get_focused_workspace(seat); if (strcmp(name, "prev") == 0) { - return workspace_prev(current_workspace); + return workspace_prev(current); } else if (strcmp(name, "prev_on_output") == 0) { - return workspace_output_prev(current_output); + return workspace_output_prev(current); } else if (strcmp(name, "next") == 0) { - return workspace_next(current_workspace); + return workspace_next(current); } else if (strcmp(name, "next_on_output") == 0) { - return workspace_output_next(current_output); + return workspace_output_next(current); } else if (strcmp(name, "current") == 0) { - return current_workspace; + return current; } else if (strcasecmp(name, "back_and_forth") == 0) { return prev_workspace_name ? root_find_workspace(_workspace_by_name, (void*)prev_workspace_name) @@ -339,97 +306,68 @@ struct sway_container *workspace_by_name(const char *name) { * the end and beginning. If next is false, the previous workspace is returned, * otherwise the next one is returned. */ -static struct sway_container *workspace_output_prev_next_impl( - struct sway_container *output, int dir) { - if (!output) { - return NULL; - } - if (!sway_assert(output->type == C_OUTPUT, - "Argument must be an output, is %d", output->type)) { - return NULL; - } - +static struct sway_workspace *workspace_output_prev_next_impl( + struct sway_output *output, int dir) { struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = seat_get_focus_inactive(seat, output); - struct sway_container *workspace = (focus->type == C_WORKSPACE ? - focus : - container_parent(focus, C_WORKSPACE)); + struct sway_workspace *workspace = seat_get_focused_workspace(seat); - int index = list_find(output->children, workspace); - size_t new_index = wrap(index + dir, output->children->length); - return output->children->items[new_index]; + int index = list_find(output->workspaces, workspace); + size_t new_index = wrap(index + dir, output->workspaces->length); + return output->workspaces->items[new_index]; } /** * Get the previous or next workspace. If the first/last workspace on an output * is active, proceed to the previous/next output's previous/next workspace. */ -static struct sway_container *workspace_prev_next_impl( - struct sway_container *workspace, int dir) { - if (!workspace) { - return NULL; - } - if (!sway_assert(workspace->type == C_WORKSPACE, - "Argument must be a workspace, is %d", workspace->type)) { - return NULL; - } - - struct sway_container *output = workspace->parent; - int index = list_find(output->children, workspace); +static struct sway_workspace *workspace_prev_next_impl( + struct sway_workspace *workspace, int dir) { + struct sway_output *output = workspace->output; + int index = list_find(output->workspaces, workspace); int new_index = index + dir; - if (new_index >= 0 && new_index < output->children->length) { - return output->children->items[index + dir]; + if (new_index >= 0 && new_index < output->workspaces->length) { + return output->workspaces->items[new_index]; } // Look on a different output - int output_index = list_find(root_container.children, output); - new_index = wrap(output_index + dir, root_container.children->length); - output = root_container.children->items[new_index]; + int output_index = list_find(root->outputs, output); + new_index = wrap(output_index + dir, root->outputs->length); + output = root->outputs->items[new_index]; if (dir == 1) { - return output->children->items[0]; + return output->workspaces->items[0]; } else { - return output->children->items[output->children->length - 1]; + return output->workspaces->items[output->workspaces->length - 1]; } } -struct sway_container *workspace_output_next(struct sway_container *current) { - return workspace_output_prev_next_impl(current, 1); +struct sway_workspace *workspace_output_next(struct sway_workspace *current) { + return workspace_output_prev_next_impl(current->output, 1); } -struct sway_container *workspace_next(struct sway_container *current) { +struct sway_workspace *workspace_next(struct sway_workspace *current) { return workspace_prev_next_impl(current, 1); } -struct sway_container *workspace_output_prev(struct sway_container *current) { - return workspace_output_prev_next_impl(current, -1); +struct sway_workspace *workspace_output_prev(struct sway_workspace *current) { + return workspace_output_prev_next_impl(current->output, -1); } -struct sway_container *workspace_prev(struct sway_container *current) { +struct sway_workspace *workspace_prev(struct sway_workspace *current) { return workspace_prev_next_impl(current, -1); } -bool workspace_switch(struct sway_container *workspace, +bool workspace_switch(struct sway_workspace *workspace, bool no_auto_back_and_forth) { - if (!workspace) { - return false; - } struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = - seat_get_focus_inactive(seat, &root_container); - if (!seat || !focus) { - return false; - } - struct sway_container *active_ws = focus; - if (active_ws->type != C_WORKSPACE) { - active_ws = container_parent(focus, C_WORKSPACE); - } + struct sway_node *focus = seat_get_focus_inactive(seat, &root->node); + struct sway_workspace *active_ws = seat_get_focused_workspace(seat); if (!no_auto_back_and_forth && config->auto_back_and_forth && active_ws == workspace && prev_workspace_name) { - struct sway_container *new_ws = workspace_by_name(prev_workspace_name); + struct sway_workspace *new_ws = workspace_by_name(prev_workspace_name); workspace = new_ws ? new_ws : workspace_create(NULL, prev_workspace_name); @@ -447,21 +385,21 @@ bool workspace_switch(struct sway_container *workspace, } // Move sticky containers to new workspace - struct sway_container *next_output = workspace->parent; - struct sway_container *next_output_prev_ws = - seat_get_active_child(seat, next_output); - list_t *floating = next_output_prev_ws->sway_workspace->floating; + struct sway_output *next_output = workspace->output; + struct sway_workspace *next_output_prev_ws = + output_get_active_workspace(next_output); bool has_sticky = false; if (workspace != next_output_prev_ws) { - for (int i = 0; i < floating->length; ++i) { - struct sway_container *floater = floating->items[i]; + for (int i = 0; i < next_output_prev_ws->floating->length; ++i) { + struct sway_container *floater = + next_output_prev_ws->floating->items[i]; if (floater->is_sticky) { has_sticky = true; - container_remove_child(floater); + container_detach(floater); workspace_add_floating(workspace, floater); - if (floater == focus) { + if (&floater->node == focus) { seat_set_focus(seat, NULL); - seat_set_focus(seat, floater); + seat_set_focus(seat, &floater->node); } --i; } @@ -470,9 +408,9 @@ bool workspace_switch(struct sway_container *workspace, wlr_log(WLR_DEBUG, "Switching to workspace %p:%s", workspace, workspace->name); - struct sway_container *next = seat_get_focus_inactive(seat, workspace); + struct sway_node *next = seat_get_focus_inactive(seat, &workspace->node); if (next == NULL) { - next = workspace; + next = &workspace->node; } if (has_sticky) { // If there's a sticky container, we might be setting focus to the same @@ -483,35 +421,24 @@ bool workspace_switch(struct sway_container *workspace, workspace_consider_destroy(active_ws); } seat_set_focus(seat, next); - struct sway_container *output = container_parent(workspace, C_OUTPUT); - arrange_windows(output); + arrange_workspace(workspace); return true; } -bool workspace_is_visible(struct sway_container *ws) { - if (ws->destroying) { +bool workspace_is_visible(struct sway_workspace *ws) { + if (ws->node.destroying) { return false; } - struct sway_container *output = container_parent(ws, C_OUTPUT); - struct sway_seat *seat = input_manager_current_seat(input_manager); - struct sway_container *focus = seat_get_focus_inactive(seat, output); - if (focus->type != C_WORKSPACE) { - focus = container_parent(focus, C_WORKSPACE); - } - return focus == ws; + return output_get_active_workspace(ws->output) == ws; } -bool workspace_is_empty(struct sway_container *ws) { - if (!sway_assert(ws->type == C_WORKSPACE, "Expected a workspace")) { - return false; - } - if (ws->children->length) { +bool workspace_is_empty(struct sway_workspace *ws) { + if (ws->tiling->length) { return false; } // Sticky views are not considered to be part of this workspace - list_t *floating = ws->sway_workspace->floating; - for (int i = 0; i < floating->length; ++i) { - struct sway_container *floater = floating->items[i]; + for (int i = 0; i < ws->floating->length; ++i) { + struct sway_container *floater = ws->floating->items[i]; if (!floater->is_sticky) { return false; } @@ -523,20 +450,19 @@ static int find_output(const void *id1, const void *id2) { return strcmp(id1, id2) ? 0 : 1; } -void workspace_output_raise_priority(struct sway_container *workspace, - struct sway_container *old_output, struct sway_container *output) { - struct sway_workspace *ws = workspace->sway_workspace; - +void workspace_output_raise_priority(struct sway_workspace *ws, + struct sway_output *old_output, struct sway_output *output) { int old_index = list_seq_find(ws->output_priority, find_output, - old_output->name); + old_output->wlr_output->name); if (old_index < 0) { return; } int new_index = list_seq_find(ws->output_priority, find_output, - output->name); + output->wlr_output->name); if (new_index < 0) { - list_insert(ws->output_priority, old_index, strdup(output->name)); + list_insert(ws->output_priority, old_index, + strdup(output->wlr_output->name)); } else if (new_index > old_index) { char *name = ws->output_priority->items[new_index]; list_del(ws->output_priority, new_index); @@ -544,29 +470,24 @@ void workspace_output_raise_priority(struct sway_container *workspace, } } -void workspace_output_add_priority(struct sway_container *workspace, - struct sway_container *output) { - int index = list_seq_find(workspace->sway_workspace->output_priority, - find_output, output->name); +void workspace_output_add_priority(struct sway_workspace *workspace, + struct sway_output *output) { + int index = list_seq_find(workspace->output_priority, + find_output, output->wlr_output->name); if (index < 0) { - list_add(workspace->sway_workspace->output_priority, - strdup(output->name)); + list_add(workspace->output_priority, strdup(output->wlr_output->name)); } } -static bool _output_by_name(struct sway_container *output, void *data) { - return output->type == C_OUTPUT && strcasecmp(output->name, data) == 0; -} - -struct sway_container *workspace_output_get_highest_available( - struct sway_container *ws, struct sway_container *exclude) { - for (int i = 0; i < ws->sway_workspace->output_priority->length; i++) { - char *name = ws->sway_workspace->output_priority->items[i]; - if (exclude && strcasecmp(name, exclude->name) == 0) { +struct sway_output *workspace_output_get_highest_available( + struct sway_workspace *ws, struct sway_output *exclude) { + for (int i = 0; i < ws->output_priority->length; i++) { + char *name = ws->output_priority->items[i]; + if (exclude && strcasecmp(name, exclude->wlr_output->name) == 0) { continue; } - struct sway_container *output = root_find_output(_output_by_name, name); + struct sway_output *output = output_by_name(name); if (output) { return output; } @@ -576,49 +497,42 @@ struct sway_container *workspace_output_get_highest_available( } static bool find_urgent_iterator(struct sway_container *con, void *data) { - return con->type == C_VIEW && view_is_urgent(con->sway_view); + return con->view && view_is_urgent(con->view); } -void workspace_detect_urgent(struct sway_container *workspace) { +void workspace_detect_urgent(struct sway_workspace *workspace) { bool new_urgent = (bool)workspace_find_container(workspace, find_urgent_iterator, NULL); - if (workspace->sway_workspace->urgent != new_urgent) { - workspace->sway_workspace->urgent = new_urgent; + if (workspace->urgent != new_urgent) { + workspace->urgent = new_urgent; ipc_event_workspace(NULL, workspace, "urgent"); - container_damage_whole(workspace); + output_damage_whole(workspace->output); } } -void workspace_for_each_container(struct sway_container *ws, +void workspace_for_each_container(struct sway_workspace *ws, void (*f)(struct sway_container *con, void *data), void *data) { - if (!sway_assert(ws->type == C_WORKSPACE, "Expected a workspace")) { - return; - } // Tiling - for (int i = 0; i < ws->children->length; ++i) { - struct sway_container *container = ws->children->items[i]; + for (int i = 0; i < ws->tiling->length; ++i) { + struct sway_container *container = ws->tiling->items[i]; f(container, data); container_for_each_child(container, f, data); } // Floating - for (int i = 0; i < ws->sway_workspace->floating->length; ++i) { - struct sway_container *container = - ws->sway_workspace->floating->items[i]; + for (int i = 0; i < ws->floating->length; ++i) { + struct sway_container *container = ws->floating->items[i]; f(container, data); container_for_each_child(container, f, data); } } -struct sway_container *workspace_find_container(struct sway_container *ws, +struct sway_container *workspace_find_container(struct sway_workspace *ws, bool (*test)(struct sway_container *con, void *data), void *data) { - if (!sway_assert(ws->type == C_WORKSPACE, "Expected a workspace")) { - return NULL; - } struct sway_container *result = NULL; // Tiling - for (int i = 0; i < ws->children->length; ++i) { - struct sway_container *child = ws->children->items[i]; + for (int i = 0; i < ws->tiling->length; ++i) { + struct sway_container *child = ws->tiling->items[i]; if (test(child, data)) { return child; } @@ -627,8 +541,8 @@ struct sway_container *workspace_find_container(struct sway_container *ws, } } // Floating - for (int i = 0; i < ws->sway_workspace->floating->length; ++i) { - struct sway_container *child = ws->sway_workspace->floating->items[i]; + for (int i = 0; i < ws->floating->length; ++i) { + struct sway_container *child = ws->floating->items[i]; if (test(child, data)) { return child; } @@ -639,37 +553,76 @@ struct sway_container *workspace_find_container(struct sway_container *ws, return NULL; } -struct sway_container *workspace_wrap_children(struct sway_container *ws) { - struct sway_container *middle = container_create(C_CONTAINER); +struct sway_container *workspace_wrap_children(struct sway_workspace *ws) { + struct sway_container *middle = container_create(NULL); middle->layout = ws->layout; - while (ws->children->length) { - struct sway_container *child = ws->children->items[0]; - container_remove_child(child); + while (ws->tiling->length) { + struct sway_container *child = ws->tiling->items[0]; + container_detach(child); container_add_child(middle, child); } - container_add_child(ws, middle); + workspace_add_tiling(ws, middle); return middle; } -void workspace_add_floating(struct sway_container *workspace, - struct sway_container *con) { - if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { - return; +void workspace_detach(struct sway_workspace *workspace) { + struct sway_output *output = workspace->output; + int index = list_find(output->workspaces, workspace); + if (index != -1) { + list_del(output->workspaces, index); } - if (!sway_assert(con->parent == NULL, "Expected an orphan container")) { - return; + workspace->output = NULL; + + node_set_dirty(&workspace->node); + node_set_dirty(&output->node); +} + +static void set_workspace(struct sway_container *container, void *data) { + container->workspace = container->parent->workspace; +} + +void workspace_add_tiling(struct sway_workspace *workspace, + struct sway_container *con) { + if (con->workspace) { + container_detach(con); } + list_add(workspace->tiling, con); + con->workspace = workspace; + container_for_each_child(con, set_workspace, NULL); + container_handle_fullscreen_reparent(con); + workspace_update_representation(workspace); + node_set_dirty(&workspace->node); + node_set_dirty(&con->node); +} - list_add(workspace->sway_workspace->floating, con); - con->parent = workspace; - container_set_dirty(workspace); - container_set_dirty(con); +void workspace_add_floating(struct sway_workspace *workspace, + struct sway_container *con) { + if (con->workspace) { + container_detach(con); + } + list_add(workspace->floating, con); + con->workspace = workspace; + container_for_each_child(con, set_workspace, NULL); + container_handle_fullscreen_reparent(con); + node_set_dirty(&workspace->node); + node_set_dirty(&con->node); } -void workspace_remove_gaps(struct sway_container *ws) { - if (!sway_assert(ws->type == C_WORKSPACE, "Expected a workspace")) { - return; +void workspace_insert_tiling(struct sway_workspace *workspace, + struct sway_container *con, int index) { + if (con->workspace) { + container_detach(con); } + list_insert(workspace->tiling, index, con); + con->workspace = workspace; + container_for_each_child(con, set_workspace, NULL); + container_handle_fullscreen_reparent(con); + workspace_update_representation(workspace); + node_set_dirty(&workspace->node); + node_set_dirty(&con->node); +} + +void workspace_remove_gaps(struct sway_workspace *ws) { if (ws->current_gaps == 0) { return; } @@ -681,15 +634,12 @@ void workspace_remove_gaps(struct sway_container *ws) { ws->current_gaps = 0; } -void workspace_add_gaps(struct sway_container *ws) { - if (!sway_assert(ws->type == C_WORKSPACE, "Expected a workspace")) { - return; - } +void workspace_add_gaps(struct sway_workspace *ws) { if (ws->current_gaps > 0) { return; } bool should_apply = - config->edge_gaps || (config->smart_gaps && ws->children->length > 1); + config->edge_gaps || (config->smart_gaps && ws->tiling->length > 1); if (!should_apply) { return; } @@ -708,3 +658,36 @@ void workspace_add_gaps(struct sway_container *ws) { ws->width -= 2 * ws->current_gaps; ws->height -= 2 * ws->current_gaps; } + +struct sway_container *workspace_split(struct sway_workspace *workspace, + enum sway_container_layout layout) { + if (workspace->tiling->length == 0) { + workspace->prev_split_layout = workspace->layout; + workspace->layout = layout; + return NULL; + } + + enum sway_container_layout old_layout = workspace->layout; + struct sway_container *middle = workspace_wrap_children(workspace); + workspace->layout = layout; + middle->layout = old_layout; + + return middle; +} + +void workspace_update_representation(struct sway_workspace *ws) { + size_t len = container_build_representation(ws->layout, ws->tiling, NULL); + free(ws->representation); + ws->representation = calloc(len + 1, sizeof(char)); + if (!sway_assert(ws->representation, "Unable to allocate title string")) { + return; + } + container_build_representation(ws->layout, ws->tiling, ws->representation); +} + +void workspace_get_box(struct sway_workspace *workspace, struct wlr_box *box) { + box->x = workspace->x; + box->y = workspace->y; + box->width = workspace->width; + box->height = workspace->height; +} |