diff options
Diffstat (limited to 'sway/tree/workspace.c')
-rw-r--r-- | sway/tree/workspace.c | 126 |
1 files changed, 94 insertions, 32 deletions
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 05cda5c0..4be63311 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -33,14 +33,15 @@ struct workspace_config *workspace_find_config(const char *ws_name) { struct sway_output *workspace_get_initial_output(const char *name) { // Check workspace configs for a workspace<->output pair struct workspace_config *wsc = workspace_find_config(name); - if (wsc && wsc->output) { - struct sway_output *output = output_by_name(wsc->output); - if (!output) { - output = output_by_identifier(wsc->output); - } - - if (output) { - return output; + if (wsc) { + for (int i = 0; i < wsc->outputs->length; i++) { + struct sway_output *output = output_by_name(wsc->outputs->items[i]); + if (!output) { + output = output_by_identifier(wsc->outputs->items[i]); + } + if (output) { + return output; + } } } // Otherwise put it on the focused output @@ -49,6 +50,21 @@ struct sway_output *workspace_get_initial_output(const char *name) { return focus->output; } +static void prevent_invalid_outer_gaps(struct sway_workspace *ws) { + if (ws->gaps_outer.top < -ws->gaps_inner) { + ws->gaps_outer.top = -ws->gaps_inner; + } + if (ws->gaps_outer.right < -ws->gaps_inner) { + ws->gaps_outer.right = -ws->gaps_inner; + } + if (ws->gaps_outer.bottom < -ws->gaps_inner) { + ws->gaps_outer.bottom = -ws->gaps_inner; + } + if (ws->gaps_outer.left < -ws->gaps_inner) { + ws->gaps_outer.left = -ws->gaps_inner; + } +} + struct sway_workspace *workspace_create(struct sway_output *output, const char *name) { if (output == NULL) { @@ -70,22 +86,41 @@ struct sway_workspace *workspace_create(struct sway_output *output, ws->floating = create_list(); ws->tiling = create_list(); ws->output_priority = create_list(); - workspace_output_add_priority(ws, output); ws->gaps_outer = config->gaps_outer; ws->gaps_inner = config->gaps_inner; if (name) { struct workspace_config *wsc = workspace_find_config(name); if (wsc) { - if (wsc->gaps_outer != INT_MIN) { - ws->gaps_outer = wsc->gaps_outer; + if (wsc->gaps_outer.top != INT_MIN) { + ws->gaps_outer.top = wsc->gaps_outer.top; + } + if (wsc->gaps_outer.right != INT_MIN) { + ws->gaps_outer.right = wsc->gaps_outer.right; + } + if (wsc->gaps_outer.bottom != INT_MIN) { + ws->gaps_outer.bottom = wsc->gaps_outer.bottom; + } + if (wsc->gaps_outer.left != INT_MIN) { + ws->gaps_outer.left = wsc->gaps_outer.left; } if (wsc->gaps_inner != INT_MIN) { ws->gaps_inner = wsc->gaps_inner; } + // Since default outer gaps can be smaller than the negation of + // workspace specific inner gaps, check outer gaps again + prevent_invalid_outer_gaps(ws); + + // Add output priorities + for (int i = 0; i < wsc->outputs->length; ++i) { + list_add(ws->output_priority, strdup(wsc->outputs->items[i])); + } } } + // If not already added, add the output to the lowest priority + workspace_output_add_priority(ws, output); + output_add_workspace(output, ws); output_sort_workspaces(output); @@ -107,8 +142,7 @@ void workspace_destroy(struct sway_workspace *workspace) { free(workspace->name); free(workspace->representation); - list_foreach(workspace->output_priority, free); - list_free(workspace->output_priority); + free_flat_list(workspace->output_priority); list_free(workspace->floating); list_free(workspace->tiling); list_free(workspace->current.floating); @@ -150,8 +184,19 @@ static bool workspace_valid_on_output(const char *output_name, char identifier[128]; struct sway_output *output = output_by_name(output_name); output_get_identifier(identifier, sizeof(identifier), output); - - return !wsc || !wsc->output || strcmp(wsc->output, output_name) == 0 || strcasecmp(identifier, output_name) == 0; + + if (!wsc) { + return true; + } + + for (int i = 0; i < wsc->outputs->length; i++) { + if (strcmp(wsc->outputs->items[i], output_name) == 0 || + strcmp(wsc->outputs->items[i], identifier) == 0) { + return true; + } + } + + return false; } static void workspace_name_from_binding(const struct sway_binding * binding, @@ -254,10 +299,19 @@ char *workspace_next_name(const char *output_name) { for (int i = 0; i < config->workspace_configs->length; ++i) { // Unlike with bindings, this does not guarantee order const struct workspace_config *wsc = config->workspace_configs->items[i]; - if (wsc->output && strcmp(wsc->output, output_name) == 0 - && workspace_by_name(wsc->workspace) == NULL) { - free(target); - target = strdup(wsc->workspace); + if (workspace_by_name(wsc->workspace)) { + continue; + } + bool found = false; + for (int j = 0; j < wsc->outputs->length; ++j) { + if (strcmp(wsc->outputs->items[j], output_name) == 0) { + found = true; + free(target); + target = strdup(wsc->workspace); + break; + } + } + if (found) { break; } } @@ -615,19 +669,25 @@ void workspace_insert_tiling(struct sway_workspace *workspace, } void workspace_remove_gaps(struct sway_workspace *ws) { - if (ws->current_gaps == 0) { + if (ws->current_gaps.top == 0 && ws->current_gaps.right == 0 && + ws->current_gaps.bottom == 0 && ws->current_gaps.left == 0) { return; } - ws->width += ws->current_gaps * 2; - ws->height += ws->current_gaps * 2; - ws->x -= ws->current_gaps; - ws->y -= ws->current_gaps; - ws->current_gaps = 0; + ws->width += ws->current_gaps.left + ws->current_gaps.right; + ws->height += ws->current_gaps.top + ws->current_gaps.bottom; + ws->x -= ws->current_gaps.left; + ws->y -= ws->current_gaps.top; + + ws->current_gaps.top = 0; + ws->current_gaps.right = 0; + ws->current_gaps.bottom = 0; + ws->current_gaps.left = 0; } void workspace_add_gaps(struct sway_workspace *ws) { - if (ws->current_gaps > 0) { + if (ws->current_gaps.top > 0 || ws->current_gaps.right > 0 || + ws->current_gaps.bottom > 0 || ws->current_gaps.left > 0) { return; } if (config->smart_gaps) { @@ -643,18 +703,20 @@ void workspace_add_gaps(struct sway_workspace *ws) { } ws->current_gaps = ws->gaps_outer; - if (ws->layout == L_TABBED || ws->layout == L_STACKED) { // We have to add inner gaps for this, because children of tabbed and // stacked containers don't apply their own gaps - they assume the // tabbed/stacked container is using gaps. - ws->current_gaps += ws->gaps_inner; + ws->current_gaps.top += ws->gaps_inner; + ws->current_gaps.right += ws->gaps_inner; + ws->current_gaps.bottom += ws->gaps_inner; + ws->current_gaps.left += ws->gaps_inner; } - ws->x += ws->current_gaps; - ws->y += ws->current_gaps; - ws->width -= 2 * ws->current_gaps; - ws->height -= 2 * ws->current_gaps; + ws->x += ws->current_gaps.left; + ws->y += ws->current_gaps.top; + ws->width -= ws->current_gaps.left + ws->current_gaps.right; + ws->height -= ws->current_gaps.top + ws->current_gaps.bottom; } struct sway_container *workspace_split(struct sway_workspace *workspace, |