aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/config.h13
-rw-r--r--include/sway/tree/workspace.h2
-rw-r--r--sway/commands/workspace.c38
-rw-r--r--sway/config.c11
-rw-r--r--sway/tree/workspace.c49
5 files changed, 66 insertions, 47 deletions
diff --git a/include/sway/config.h b/include/sway/config.h
index 35f0e708..af5c7a18 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -167,13 +167,12 @@ struct output_config {
167}; 167};
168 168
169/** 169/**
170 * Maps a workspace name to an output name. 170 * Stores configuration for a workspace, regardless of whether the workspace
171 * 171 * exists.
172 * Set via `workspace <x> output <y>`
173 */ 172 */
174struct workspace_output { 173struct workspace_config {
175 char *output;
176 char *workspace; 174 char *workspace;
175 char *output;
177}; 176};
178 177
179struct bar_config { 178struct bar_config {
@@ -327,7 +326,7 @@ struct sway_config {
327 list_t *modes; 326 list_t *modes;
328 list_t *bars; 327 list_t *bars;
329 list_t *cmd_queue; 328 list_t *cmd_queue;
330 list_t *workspace_outputs; 329 list_t *workspace_configs;
331 list_t *output_configs; 330 list_t *output_configs;
332 list_t *input_configs; 331 list_t *input_configs;
333 list_t *seat_configs; 332 list_t *seat_configs;
@@ -518,6 +517,8 @@ struct bar_config *default_bar_config(void);
518 517
519void free_bar_config(struct bar_config *bar); 518void free_bar_config(struct bar_config *bar);
520 519
520void free_workspace_config(struct workspace_config *wsc);
521
521/** 522/**
522 * Updates the value of config->font_height based on the max title height 523 * Updates the value of config->font_height based on the max title height
523 * reported by each container. If recalculate is true, the containers will 524 * reported by each container. If recalculate is true, the containers will
diff --git a/include/sway/tree/workspace.h b/include/sway/tree/workspace.h
index e4b616d1..c8220b39 100644
--- a/include/sway/tree/workspace.h
+++ b/include/sway/tree/workspace.h
@@ -48,6 +48,8 @@ struct sway_workspace {
48 48
49extern char *prev_workspace_name; 49extern char *prev_workspace_name;
50 50
51struct workspace_config *workspace_find_config(const char *ws_name);
52
51struct sway_output *workspace_get_initial_output(const char *name); 53struct sway_output *workspace_get_initial_output(const char *name);
52 54
53struct sway_workspace *workspace_create(struct sway_output *output, 55struct sway_workspace *workspace_create(struct sway_output *output,
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c
index f026a39d..2ce7872d 100644
--- a/sway/commands/workspace.c
+++ b/sway/commands/workspace.c
@@ -10,6 +10,26 @@
10#include "log.h" 10#include "log.h"
11#include "stringop.h" 11#include "stringop.h"
12 12
13static struct workspace_config *workspace_config_find_or_create(char *ws_name) {
14 struct workspace_config *wsc = workspace_find_config(ws_name);
15 if (wsc) {
16 return wsc;
17 }
18 wsc = calloc(1, sizeof(struct workspace_config));
19 if (!wsc) {
20 return NULL;
21 }
22 wsc->workspace = strdup(ws_name);
23 list_add(config->workspace_configs, wsc);
24 return wsc;
25}
26
27void free_workspace_config(struct workspace_config *wsc) {
28 free(wsc->workspace);
29 free(wsc->output);
30 free(wsc);
31}
32
13struct cmd_results *cmd_workspace(int argc, char **argv) { 33struct cmd_results *cmd_workspace(int argc, char **argv) {
14 struct cmd_results *error = NULL; 34 struct cmd_results *error = NULL;
15 if ((error = checkarg(argc, "workspace", EXPECTED_AT_LEAST, 1))) { 35 if ((error = checkarg(argc, "workspace", EXPECTED_AT_LEAST, 1))) {
@@ -28,21 +48,15 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
28 if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO, output_location + 2))) { 48 if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO, output_location + 2))) {
29 return error; 49 return error;
30 } 50 }
31 struct workspace_output *wso = calloc(1, sizeof(struct workspace_output)); 51 char *ws_name = join_args(argv, argc - 2);
32 if (!wso) { 52 struct workspace_config *wsc = workspace_config_find_or_create(ws_name);
53 free(ws_name);
54 if (!wsc) {
33 return cmd_results_new(CMD_FAILURE, "workspace output", 55 return cmd_results_new(CMD_FAILURE, "workspace output",
34 "Unable to allocate workspace output"); 56 "Unable to allocate workspace output");
35 } 57 }
36 wso->workspace = join_args(argv, argc - 2); 58 free(wsc->output);
37 wso->output = strdup(argv[output_location + 1]); 59 wsc->output = strdup(argv[output_location + 1]);
38 int i = -1;
39 if ((i = list_seq_find(config->workspace_outputs, workspace_output_cmp_workspace, wso)) != -1) {
40 struct workspace_output *old = config->workspace_outputs->items[i];
41 free(old); // workspaces can only be assigned to a single output
42 list_del(config->workspace_outputs, i);
43 }
44 wlr_log(WLR_DEBUG, "Assigning workspace %s to output %s", wso->workspace, wso->output);
45 list_add(config->workspace_outputs, wso);
46 } else { 60 } else {
47 if (config->reading || !config->active) { 61 if (config->reading || !config->active) {
48 return cmd_results_new(CMD_DEFER, "workspace", NULL); 62 return cmd_results_new(CMD_DEFER, "workspace", NULL);
diff --git a/sway/config.c b/sway/config.c
index 830fb65f..1e08559d 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -95,7 +95,12 @@ void free_config(struct sway_config *config) {
95 list_free(config->bars); 95 list_free(config->bars);
96 } 96 }
97 list_free(config->cmd_queue); 97 list_free(config->cmd_queue);
98 list_free(config->workspace_outputs); 98 if (config->workspace_configs) {
99 for (int i = 0; i < config->workspace_configs->length; i++) {
100 free_workspace_config(config->workspace_configs->items[i]);
101 }
102 list_free(config->workspace_configs);
103 }
99 if (config->output_configs) { 104 if (config->output_configs) {
100 for (int i = 0; i < config->output_configs->length; i++) { 105 for (int i = 0; i < config->output_configs->length; i++) {
101 free_output_config(config->output_configs->items[i]); 106 free_output_config(config->output_configs->items[i]);
@@ -175,7 +180,7 @@ static void config_defaults(struct sway_config *config) {
175 if (!(config->symbols = create_list())) goto cleanup; 180 if (!(config->symbols = create_list())) goto cleanup;
176 if (!(config->modes = create_list())) goto cleanup; 181 if (!(config->modes = create_list())) goto cleanup;
177 if (!(config->bars = create_list())) goto cleanup; 182 if (!(config->bars = create_list())) goto cleanup;
178 if (!(config->workspace_outputs = create_list())) goto cleanup; 183 if (!(config->workspace_configs = create_list())) goto cleanup;
179 if (!(config->criteria = create_list())) goto cleanup; 184 if (!(config->criteria = create_list())) goto cleanup;
180 if (!(config->no_focus = create_list())) goto cleanup; 185 if (!(config->no_focus = create_list())) goto cleanup;
181 if (!(config->input_configs = create_list())) goto cleanup; 186 if (!(config->input_configs = create_list())) goto cleanup;
@@ -804,7 +809,7 @@ char *do_var_replacement(char *str) {
804// would compare two structs in full, while this method only compares the 809// would compare two structs in full, while this method only compares the
805// workspace. 810// workspace.
806int workspace_output_cmp_workspace(const void *a, const void *b) { 811int workspace_output_cmp_workspace(const void *a, const void *b) {
807 const struct workspace_output *wsa = a, *wsb = b; 812 const struct workspace_config *wsa = a, *wsb = b;
808 return lenient_strcmp(wsa->workspace, wsb->workspace); 813 return lenient_strcmp(wsa->workspace, wsb->workspace);
809} 814}
810 815
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index 16031e87..e592302c 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -20,17 +20,23 @@
20#include "log.h" 20#include "log.h"
21#include "util.h" 21#include "util.h"
22 22
23struct workspace_config *workspace_find_config(const char *ws_name) {
24 for (int i = 0; i < config->workspace_configs->length; ++i) {
25 struct workspace_config *wsc = config->workspace_configs->items[i];
26 if (strcmp(wsc->workspace, ws_name) == 0) {
27 return wsc;
28 }
29 }
30 return NULL;
31}
32
23struct sway_output *workspace_get_initial_output(const char *name) { 33struct sway_output *workspace_get_initial_output(const char *name) {
24 // Search for workspace<->output pair 34 // Check workspace configs for a workspace<->output pair
25 for (int i = 0; i < config->workspace_outputs->length; ++i) { 35 struct workspace_config *wsc = workspace_find_config(name);
26 struct workspace_output *wso = config->workspace_outputs->items[i]; 36 if (wsc && wsc->output) {
27 if (strcasecmp(wso->workspace, name) == 0) { 37 struct sway_output *output = output_by_name(wsc->output);
28 // Find output to use if it exists 38 if (output) {
29 struct sway_output *output = output_by_name(wso->output); 39 return output;
30 if (output) {
31 return output;
32 }
33 break;
34 } 40 }
35 } 41 }
36 // Otherwise put it on the focused output 42 // Otherwise put it on the focused output
@@ -121,17 +127,8 @@ void next_name_map(struct sway_container *ws, void *data) {
121 127
122static bool workspace_valid_on_output(const char *output_name, 128static bool workspace_valid_on_output(const char *output_name,
123 const char *ws_name) { 129 const char *ws_name) {
124 int i; 130 struct workspace_config *wsc = workspace_find_config(ws_name);
125 for (i = 0; i < config->workspace_outputs->length; ++i) { 131 return !wsc || strcmp(wsc->output, output_name) == 0;
126 struct workspace_output *wso = config->workspace_outputs->items[i];
127 if (strcasecmp(wso->workspace, ws_name) == 0) {
128 if (strcasecmp(wso->output, output_name) != 0) {
129 return false;
130 }
131 }
132 }
133
134 return true;
135} 132}
136 133
137static void workspace_name_from_binding(const struct sway_binding * binding, 134static void workspace_name_from_binding(const struct sway_binding * binding,
@@ -231,13 +228,13 @@ char *workspace_next_name(const char *output_name) {
231 workspace_name_from_binding(mode->keycode_bindings->items[i], 228 workspace_name_from_binding(mode->keycode_bindings->items[i],
232 output_name, &order, &target); 229 output_name, &order, &target);
233 } 230 }
234 for (int i = 0; i < config->workspace_outputs->length; ++i) { 231 for (int i = 0; i < config->workspace_configs->length; ++i) {
235 // Unlike with bindings, this does not guarantee order 232 // Unlike with bindings, this does not guarantee order
236 const struct workspace_output *wso = config->workspace_outputs->items[i]; 233 const struct workspace_config *wsc = config->workspace_configs->items[i];
237 if (strcmp(wso->output, output_name) == 0 234 if (wsc->output && strcmp(wsc->output, output_name) == 0
238 && workspace_by_name(wso->workspace) == NULL) { 235 && workspace_by_name(wsc->workspace) == NULL) {
239 free(target); 236 free(target);
240 target = strdup(wso->workspace); 237 target = strdup(wsc->workspace);
241 break; 238 break;
242 } 239 }
243 } 240 }