diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2018-11-11 11:22:38 -0500 |
---|---|---|
committer | Brian Ashworth <bosrsf04@gmail.com> | 2018-11-11 11:22:38 -0500 |
commit | 12876932a948d7265745efaccafea509bdbaffe8 (patch) | |
tree | 458a3acb6db39a78d26b4ce38ea637aa21812e29 /sway/tree/workspace.c | |
parent | Merge pull request #3098 from c-edw/feature/RefactorArgParse (diff) | |
download | sway-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.c | 61 |
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) { | |||
33 | struct sway_output *workspace_get_initial_output(const char *name) { | 33 | struct 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 | ||
184 | static void workspace_name_from_binding(const struct sway_binding * binding, | 202 | static 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 | } |