aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/workspace.c
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-11-11 11:22:38 -0500
committerLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-11-11 11:22:38 -0500
commit12876932a948d7265745efaccafea509bdbaffe8 (patch)
tree458a3acb6db39a78d26b4ce38ea637aa21812e29 /sway/tree/workspace.c
parentMerge pull request #3098 from c-edw/feature/RefactorArgParse (diff)
downloadsway-12876932a948d7265745efaccafea509bdbaffe8.tar.gz
sway-12876932a948d7265745efaccafea509bdbaffe8.tar.zst
sway-12876932a948d7265745efaccafea509bdbaffe8.zip
Allow multiple outputs for workspace output
`i3 4.16` allows users to list multiple outputs for a workspace and the first available will be used. The syntax is as follows: `workspace <workspace> output <outputs...>` Additionally when the workspace is created, the outputs get added to the output priority list in the order specified. This ensures that if a higher output gets connected, the workspace will move to the higher output. This works the same way as if the user had a workspace on an output, disconnected the output, and then later reconnected the output.
Diffstat (limited to 'sway/tree/workspace.c')
-rw-r--r--sway/tree/workspace.c61
1 files changed, 44 insertions, 17 deletions
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index 93ce50de..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) {
33struct sway_output *workspace_get_initial_output(const char *name) { 33struct sway_output *workspace_get_initial_output(const char *name) {
34 // Check workspace configs for a workspace<->output pair 34 // Check workspace configs for a workspace<->output pair
35 struct workspace_config *wsc = workspace_find_config(name); 35 struct workspace_config *wsc = workspace_find_config(name);
36 if (wsc && wsc->output) { 36 if (wsc) {
37 struct sway_output *output = output_by_name(wsc->output); 37 for (int i = 0; i < wsc->outputs->length; i++) {
38 if (!output) { 38 struct sway_output *output = output_by_name(wsc->outputs->items[i]);
39 output = output_by_identifier(wsc->output); 39 if (!output) {
40 } 40 output = output_by_identifier(wsc->outputs->items[i]);
41 41 }
42 if (output) { 42 if (output) {
43 return output; 43 return output;
44 }
44 } 45 }
45 } 46 }
46 // Otherwise put it on the focused output 47 // Otherwise put it on the focused output
@@ -85,7 +86,6 @@ struct sway_workspace *workspace_create(struct sway_output *output,
85 ws->floating = create_list(); 86 ws->floating = create_list();
86 ws->tiling = create_list(); 87 ws->tiling = create_list();
87 ws->output_priority = create_list(); 88 ws->output_priority = create_list();
88 workspace_output_add_priority(ws, output);
89 89
90 ws->gaps_outer = config->gaps_outer; 90 ws->gaps_outer = config->gaps_outer;
91 ws->gaps_inner = config->gaps_inner; 91 ws->gaps_inner = config->gaps_inner;
@@ -110,9 +110,17 @@ struct sway_workspace *workspace_create(struct sway_output *output,
110 // Since default outer gaps can be smaller than the negation of 110 // Since default outer gaps can be smaller than the negation of
111 // workspace specific inner gaps, check outer gaps again 111 // workspace specific inner gaps, check outer gaps again
112 prevent_invalid_outer_gaps(ws); 112 prevent_invalid_outer_gaps(ws);
113
114 // Add output priorities
115 for (int i = 0; i < wsc->outputs->length; ++i) {
116 list_add(ws->output_priority, strdup(wsc->outputs->items[i]));
117 }
113 } 118 }
114 } 119 }
115 120
121 // If not already added, add the output to the lowest priority
122 workspace_output_add_priority(ws, output);
123
116 output_add_workspace(output, ws); 124 output_add_workspace(output, ws);
117 output_sort_workspaces(output); 125 output_sort_workspaces(output);
118 126
@@ -134,8 +142,7 @@ void workspace_destroy(struct sway_workspace *workspace) {
134 142
135 free(workspace->name); 143 free(workspace->name);
136 free(workspace->representation); 144 free(workspace->representation);
137 list_foreach(workspace->output_priority, free); 145 free_flat_list(workspace->output_priority);
138 list_free(workspace->output_priority);
139 list_free(workspace->floating); 146 list_free(workspace->floating);
140 list_free(workspace->tiling); 147 list_free(workspace->tiling);
141 list_free(workspace->current.floating); 148 list_free(workspace->current.floating);
@@ -177,8 +184,19 @@ static bool workspace_valid_on_output(const char *output_name,
177 char identifier[128]; 184 char identifier[128];
178 struct sway_output *output = output_by_name(output_name); 185 struct sway_output *output = output_by_name(output_name);
179 output_get_identifier(identifier, sizeof(identifier), output); 186 output_get_identifier(identifier, sizeof(identifier), output);
180 187
181 return !wsc || !wsc->output || strcmp(wsc->output, output_name) == 0 || strcasecmp(identifier, output_name) == 0; 188 if (!wsc) {
189 return true;
190 }
191
192 for (int i = 0; i < wsc->outputs->length; i++) {
193 if (strcmp(wsc->outputs->items[i], output_name) == 0 ||
194 strcmp(wsc->outputs->items[i], identifier) == 0) {
195 return true;
196 }
197 }
198
199 return false;
182} 200}
183 201
184static void workspace_name_from_binding(const struct sway_binding * binding, 202static void workspace_name_from_binding(const struct sway_binding * binding,
@@ -281,10 +299,19 @@ char *workspace_next_name(const char *output_name) {
281 for (int i = 0; i < config->workspace_configs->length; ++i) { 299 for (int i = 0; i < config->workspace_configs->length; ++i) {
282 // Unlike with bindings, this does not guarantee order 300 // Unlike with bindings, this does not guarantee order
283 const struct workspace_config *wsc = config->workspace_configs->items[i]; 301 const struct workspace_config *wsc = config->workspace_configs->items[i];
284 if (wsc->output && strcmp(wsc->output, output_name) == 0 302 if (workspace_by_name(wsc->workspace)) {
285 && workspace_by_name(wsc->workspace) == NULL) { 303 continue;
286 free(target); 304 }
287 target = strdup(wsc->workspace); 305 bool found = false;
306 for (int j = 0; j < wsc->outputs->length; ++j) {
307 if (strcmp(wsc->outputs->items[j], output_name) == 0) {
308 found = true;
309 free(target);
310 target = strdup(wsc->workspace);
311 break;
312 }
313 }
314 if (found) {
288 break; 315 break;
289 } 316 }
290 } 317 }