diff options
-rw-r--r-- | include/sway/config.h | 13 | ||||
-rw-r--r-- | include/sway/tree/workspace.h | 2 | ||||
-rw-r--r-- | sway/commands/workspace.c | 38 | ||||
-rw-r--r-- | sway/config.c | 11 | ||||
-rw-r--r-- | sway/tree/workspace.c | 49 |
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 | */ |
174 | struct workspace_output { | 173 | struct workspace_config { |
175 | char *output; | ||
176 | char *workspace; | 174 | char *workspace; |
175 | char *output; | ||
177 | }; | 176 | }; |
178 | 177 | ||
179 | struct bar_config { | 178 | struct 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 | ||
519 | void free_bar_config(struct bar_config *bar); | 518 | void free_bar_config(struct bar_config *bar); |
520 | 519 | ||
520 | void 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 | ||
49 | extern char *prev_workspace_name; | 49 | extern char *prev_workspace_name; |
50 | 50 | ||
51 | struct workspace_config *workspace_find_config(const char *ws_name); | ||
52 | |||
51 | struct sway_output *workspace_get_initial_output(const char *name); | 53 | struct sway_output *workspace_get_initial_output(const char *name); |
52 | 54 | ||
53 | struct sway_workspace *workspace_create(struct sway_output *output, | 55 | struct 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 | ||
13 | static 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 | |||
27 | void free_workspace_config(struct workspace_config *wsc) { | ||
28 | free(wsc->workspace); | ||
29 | free(wsc->output); | ||
30 | free(wsc); | ||
31 | } | ||
32 | |||
13 | struct cmd_results *cmd_workspace(int argc, char **argv) { | 33 | struct 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. |
806 | int workspace_output_cmp_workspace(const void *a, const void *b) { | 811 | int 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 | ||
23 | struct 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 | |||
23 | struct sway_output *workspace_get_initial_output(const char *name) { | 33 | struct 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 | ||
122 | static bool workspace_valid_on_output(const char *output_name, | 128 | static 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 | ||
137 | static void workspace_name_from_binding(const struct sway_binding * binding, | 134 | static 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 | } |