diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-11-11 11:30:27 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-11 11:30:27 -0500 |
commit | 101515eb0c0039e8f67b7d3c8269a8898d8760ac (patch) | |
tree | 458a3acb6db39a78d26b4ce38ea637aa21812e29 | |
parent | Merge pull request #3098 from c-edw/feature/RefactorArgParse (diff) | |
parent | Allow multiple outputs for workspace output (diff) | |
download | sway-101515eb0c0039e8f67b7d3c8269a8898d8760ac.tar.gz sway-101515eb0c0039e8f67b7d3c8269a8898d8760ac.tar.zst sway-101515eb0c0039e8f67b7d3c8269a8898d8760ac.zip |
Merge pull request #3108 from RedSoxFan/workspace-output-improved
Allow multiple outputs for workspace output
-rw-r--r-- | include/sway/config.h | 2 | ||||
-rw-r--r-- | sway/commands/workspace.c | 13 | ||||
-rw-r--r-- | sway/sway.5.scd | 8 | ||||
-rw-r--r-- | sway/tree/output.c | 7 | ||||
-rw-r--r-- | sway/tree/workspace.c | 61 |
5 files changed, 66 insertions, 25 deletions
diff --git a/include/sway/config.h b/include/sway/config.h index cd56c3dc..79c4359b 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -183,7 +183,7 @@ struct side_gaps { | |||
183 | */ | 183 | */ |
184 | struct workspace_config { | 184 | struct workspace_config { |
185 | char *workspace; | 185 | char *workspace; |
186 | char *output; | 186 | list_t *outputs; |
187 | int gaps_inner; | 187 | int gaps_inner; |
188 | struct side_gaps gaps_outer; | 188 | struct side_gaps gaps_outer; |
189 | }; | 189 | }; |
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c index 168494d2..92118ecf 100644 --- a/sway/commands/workspace.c +++ b/sway/commands/workspace.c | |||
@@ -21,6 +21,7 @@ static struct workspace_config *workspace_config_find_or_create(char *ws_name) { | |||
21 | return NULL; | 21 | return NULL; |
22 | } | 22 | } |
23 | wsc->workspace = strdup(ws_name); | 23 | wsc->workspace = strdup(ws_name); |
24 | wsc->outputs = create_list(); | ||
24 | wsc->gaps_inner = INT_MIN; | 25 | wsc->gaps_inner = INT_MIN; |
25 | wsc->gaps_outer.top = INT_MIN; | 26 | wsc->gaps_outer.top = INT_MIN; |
26 | wsc->gaps_outer.right = INT_MIN; | 27 | wsc->gaps_outer.right = INT_MIN; |
@@ -32,7 +33,7 @@ static struct workspace_config *workspace_config_find_or_create(char *ws_name) { | |||
32 | 33 | ||
33 | void free_workspace_config(struct workspace_config *wsc) { | 34 | void free_workspace_config(struct workspace_config *wsc) { |
34 | free(wsc->workspace); | 35 | free(wsc->workspace); |
35 | free(wsc->output); | 36 | free_flat_list(wsc->outputs); |
36 | free(wsc); | 37 | free(wsc); |
37 | } | 38 | } |
38 | 39 | ||
@@ -141,18 +142,20 @@ struct cmd_results *cmd_workspace(int argc, char **argv) { | |||
141 | } | 142 | } |
142 | } | 143 | } |
143 | if (output_location >= 0) { | 144 | if (output_location >= 0) { |
144 | if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO, output_location + 2))) { | 145 | if ((error = checkarg(argc, "workspace", EXPECTED_AT_LEAST, |
146 | output_location + 2))) { | ||
145 | return error; | 147 | return error; |
146 | } | 148 | } |
147 | char *ws_name = join_args(argv, argc - 2); | 149 | char *ws_name = join_args(argv, output_location); |
148 | struct workspace_config *wsc = workspace_config_find_or_create(ws_name); | 150 | struct workspace_config *wsc = workspace_config_find_or_create(ws_name); |
149 | free(ws_name); | 151 | free(ws_name); |
150 | if (!wsc) { | 152 | if (!wsc) { |
151 | return cmd_results_new(CMD_FAILURE, "workspace output", | 153 | return cmd_results_new(CMD_FAILURE, "workspace output", |
152 | "Unable to allocate workspace output"); | 154 | "Unable to allocate workspace output"); |
153 | } | 155 | } |
154 | free(wsc->output); | 156 | for (int i = output_location + 1; i < argc; ++i) { |
155 | wsc->output = strdup(argv[output_location + 1]); | 157 | list_add(wsc->outputs, strdup(argv[i])); |
158 | } | ||
156 | } else if (gaps_location >= 0) { | 159 | } else if (gaps_location >= 0) { |
157 | if ((error = cmd_workspace_gaps(argc, argv, gaps_location))) { | 160 | if ((error = cmd_workspace_gaps(argc, argv, gaps_location))) { |
158 | return error; | 161 | return error; |
diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 8f6b35f1..1a11015f 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd | |||
@@ -573,8 +573,12 @@ The default colors are: | |||
573 | Specifies that workspace _name_ should have the given gaps settings when it | 573 | Specifies that workspace _name_ should have the given gaps settings when it |
574 | is created. | 574 | is created. |
575 | 575 | ||
576 | *workspace* <name> output <output> | 576 | *workspace* <name> output <outputs...> |
577 | Specifies that workspace _name_ should be shown on the specified _output_. | 577 | Specifies that workspace _name_ should be shown on the specified _outputs_. |
578 | Multiple outputs can be listed and the first available will be used. If the | ||
579 | workspace gets placed on an output further down the list and an output that | ||
580 | is higher on the list becomes available, the workspace will be move to the | ||
581 | higher priority output. | ||
578 | 582 | ||
579 | *workspace\_auto\_back\_and\_forth* yes|no | 583 | *workspace\_auto\_back\_and\_forth* yes|no |
580 | When _yes_, repeating a workspace switch command will switch back to the | 584 | When _yes_, repeating a workspace switch command will switch back to the |
diff --git a/sway/tree/output.c b/sway/tree/output.c index 2704920d..3c4614a8 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c | |||
@@ -31,6 +31,13 @@ static void restore_workspaces(struct sway_output *output) { | |||
31 | j--; | 31 | j--; |
32 | } | 32 | } |
33 | } | 33 | } |
34 | |||
35 | if (other->workspaces->length == 0) { | ||
36 | char *next = workspace_next_name(other->wlr_output->name); | ||
37 | struct sway_workspace *ws = workspace_create(other, next); | ||
38 | free(next); | ||
39 | ipc_event_workspace(NULL, ws, "init"); | ||
40 | } | ||
34 | } | 41 | } |
35 | 42 | ||
36 | // Saved workspaces | 43 | // Saved workspaces |
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 | } |