summaryrefslogtreecommitdiff
path: root/sway/tree/workspace.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/workspace.c')
-rw-r--r--sway/tree/workspace.c126
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,