diff options
Diffstat (limited to 'sway/tree/workspace.c')
-rw-r--r-- | sway/tree/workspace.c | 146 |
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); +} |