aboutsummaryrefslogtreecommitdiff
path: root/sway/tree/workspace.c
diff options
context:
space:
mode:
authorDrew DeVault <sir@cmpwn.com>2018-09-05 09:33:27 -0400
committerGitHub <noreply@github.com>2018-09-05 09:33:27 -0400
commit610eb946171f782165a20614b2d3318b89273990 (patch)
tree05eec1df1ef48e05b23d273d31143ad32e7632d2 /sway/tree/workspace.c
parentaa2bf98e0442f9bf41a852c2fafee5b0897010a2 (diff)
parentdbf4aa3e33bdee53876c6893b15ac3f224818e7c (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.c493
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;
+}