aboutsummaryrefslogtreecommitdiff
path: root/sway/tree/workspace.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/workspace.c')
-rw-r--r--sway/tree/workspace.c146
1 files changed, 109 insertions, 37 deletions
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index cd2a7a04..cf50ee09 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -67,26 +67,19 @@ struct sway_container *workspace_create(struct sway_container *output,
return NULL;
}
swayws->swayc = workspace;
- swayws->floating = container_create(C_CONTAINER);
- swayws->floating->parent = swayws->swayc;
- swayws->floating->layout = L_FLOATING;
+ swayws->floating = create_list();
swayws->output_priority = create_list();
workspace->sway_workspace = swayws;
workspace_output_add_priority(workspace, output);
container_add_child(output, workspace);
- container_sort_workspaces(output);
+ output_sort_workspaces(output);
container_create_notify(workspace);
return workspace;
}
char *prev_workspace_name = NULL;
-struct workspace_by_number_data {
- int len;
- const char *cset;
- const char *name;
-};
void next_name_map(struct sway_container *ws, void *data) {
int *count = data;
@@ -154,7 +147,7 @@ static void workspace_name_from_binding(const struct sway_binding * binding,
wlr_log(WLR_DEBUG, "Isolated name from workspace number: '%s'", _target);
// Make sure the workspace number doesn't already exist
- if (workspace_by_number(_target)) {
+ if (isdigit(_target[0]) && workspace_by_number(_target)) {
free(_target);
free(dup);
return;
@@ -212,6 +205,7 @@ char *workspace_next_name(const char *output_name) {
&& workspace_by_name(wso->workspace) == NULL) {
free(target);
target = strdup(wso->workspace);
+ break;
}
}
if (target != NULL) {
@@ -233,19 +227,18 @@ static bool _workspace_by_number(struct sway_container *view, void *data) {
if (view->type != C_WORKSPACE) {
return false;
}
- struct workspace_by_number_data *wbnd = data;
- int a = strspn(view->name, wbnd->cset);
- return a == wbnd->len && strncmp(view->name, wbnd->name, a) == 0;
+ char *name = data;
+ char *view_name = view->name;
+ while (isdigit(*name)) {
+ if (*name++ != *view_name++) {
+ return false;
+ }
+ }
+ return !isdigit(*view_name);
}
struct sway_container *workspace_by_number(const char* name) {
- struct workspace_by_number_data wbnd = {0, "1234567890", name};
- wbnd.len = strspn(name, wbnd.cset);
- if (wbnd.len <= 0) {
- return NULL;
- }
- return container_find(&root_container,
- _workspace_by_number, (void *) &wbnd);
+ return root_find_workspace(_workspace_by_number, (void *) name);
}
static bool _workspace_by_name(struct sway_container *view, void *data) {
@@ -258,7 +251,8 @@ struct sway_container *workspace_by_name(const char *name) {
struct sway_container *current_workspace = NULL, *current_output = NULL;
struct sway_container *focus = seat_get_focus(seat);
if (focus) {
- current_workspace = container_parent(focus, C_WORKSPACE);
+ current_workspace = focus->type == C_WORKSPACE ?
+ focus : container_parent(focus, C_WORKSPACE);
current_output = container_parent(focus, C_OUTPUT);
}
@@ -273,11 +267,11 @@ struct sway_container *workspace_by_name(const char *name) {
} else if (strcmp(name, "current") == 0) {
return current_workspace;
} else if (strcasecmp(name, "back_and_forth") == 0) {
- return prev_workspace_name ? container_find(&root_container,
- _workspace_by_name, (void *)prev_workspace_name) : NULL;
+ return prev_workspace_name ?
+ root_find_workspace(_workspace_by_name, (void*)prev_workspace_name)
+ : NULL;
} else {
- return container_find(&root_container, _workspace_by_name,
- (void *)name);
+ return root_find_workspace(_workspace_by_name, (void*)name);
}
}
@@ -397,17 +391,15 @@ bool workspace_switch(struct sway_container *workspace,
struct sway_container *next_output = workspace->parent;
struct sway_container *next_output_prev_ws =
seat_get_active_child(seat, next_output);
- struct sway_container *floating =
- next_output_prev_ws->sway_workspace->floating;
+ list_t *floating = next_output_prev_ws->sway_workspace->floating;
bool has_sticky = false;
if (workspace != next_output_prev_ws) {
- for (int i = 0; i < floating->children->length; ++i) {
- struct sway_container *floater = floating->children->items[i];
+ for (int i = 0; i < floating->length; ++i) {
+ struct sway_container *floater = floating->items[i];
if (floater->is_sticky) {
has_sticky = true;
container_remove_child(floater);
- container_add_child(workspace->sway_workspace->floating,
- floater);
+ workspace_add_floating(workspace, floater);
if (floater == focus) {
seat_set_focus(seat, NULL);
seat_set_focus(seat, floater);
@@ -460,9 +452,9 @@ bool workspace_is_empty(struct sway_container *ws) {
return false;
}
// Sticky views are not considered to be part of this workspace
- struct sway_container *floating = ws->sway_workspace->floating;
- for (int i = 0; i < floating->children->length; ++i) {
- struct sway_container *floater = floating->children->items[i];
+ list_t *floating = ws->sway_workspace->floating;
+ for (int i = 0; i < floating->length; ++i) {
+ struct sway_container *floater = floating->items[i];
if (!floater->is_sticky) {
return false;
}
@@ -517,8 +509,7 @@ struct sway_container *workspace_output_get_highest_available(
continue;
}
- struct sway_container *output = container_find(&root_container,
- _output_by_name, name);
+ struct sway_container *output = root_find_output(_output_by_name, name);
if (output) {
return output;
}
@@ -527,8 +518,13 @@ struct sway_container *workspace_output_get_highest_available(
return NULL;
}
+static bool find_urgent_iterator(struct sway_container *con, void *data) {
+ return con->type == C_VIEW && view_is_urgent(con->sway_view);
+}
+
void workspace_detect_urgent(struct sway_container *workspace) {
- bool new_urgent = container_has_urgent_child(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;
@@ -536,3 +532,79 @@ void workspace_detect_urgent(struct sway_container *workspace) {
container_damage_whole(workspace);
}
}
+
+void workspace_for_each_container(struct sway_container *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];
+ 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];
+ f(container, data);
+ container_for_each_child(container, f, data);
+ }
+}
+
+struct sway_container *workspace_find_container(struct sway_container *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];
+ if (test(child, data)) {
+ return child;
+ }
+ if ((result = container_find_child(child, test, data))) {
+ return result;
+ }
+ }
+ // Floating
+ for (int i = 0; i < ws->sway_workspace->floating->length; ++i) {
+ struct sway_container *child = ws->sway_workspace->floating->items[i];
+ if (test(child, data)) {
+ return child;
+ }
+ if ((result = container_find_child(child, test, data))) {
+ return result;
+ }
+ }
+ return NULL;
+}
+
+struct sway_container *workspace_wrap_children(struct sway_container *ws) {
+ struct sway_container *middle = container_create(C_CONTAINER);
+ middle->layout = ws->layout;
+ while (ws->children->length) {
+ struct sway_container *child = ws->children->items[0];
+ container_remove_child(child);
+ container_add_child(middle, child);
+ }
+ container_add_child(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;
+ }
+ if (!sway_assert(con->parent == NULL, "Expected an orphan container")) {
+ return;
+ }
+
+ list_add(workspace->sway_workspace->floating, con);
+ con->parent = workspace;
+ container_set_dirty(workspace);
+ container_set_dirty(con);
+}