diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-09-28 21:58:23 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-09-28 22:35:38 +1000 |
commit | 138d10d5d62a25c2e00bd9051c835b9e78a36de4 (patch) | |
tree | d967c524a4016695a48a48534ee3dac17c28e038 /sway | |
parent | Merge pull request #2720 from swaywm/swaylock-shadow (diff) | |
download | sway-138d10d5d62a25c2e00bd9051c835b9e78a36de4.tar.gz sway-138d10d5d62a25c2e00bd9051c835b9e78a36de4.tar.zst sway-138d10d5d62a25c2e00bd9051c835b9e78a36de4.zip |
Rename workspace_outputs to workspace_configs and fix memory leak
When we eventually implement `workspace <ws> gaps inner|outer <px>`,
we'll need to store the gaps settings for workspaces before they're
created. Rather than create a workspace_gaps struct, the approach I'm
taking is to rename workspace_outputs to workspace_configs and then add
gaps settings to that.
I've added a lookup function workspace_find_config. Note that we have a
similar thing for outputs (output_config struct and output_find_config).
Lastly, when freeing config it would create a memory leak by freeing the
list items but not the workspace or output names inside them. This has
been rectified using a free_workspace_config function.
Diffstat (limited to 'sway')
-rw-r--r-- | sway/commands/workspace.c | 38 | ||||
-rw-r--r-- | sway/config.c | 11 | ||||
-rw-r--r-- | sway/tree/workspace.c | 49 |
3 files changed, 57 insertions, 41 deletions
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 | } |