diff options
-rw-r--r-- | sway/config.c | 185 | ||||
-rw-r--r-- | sway/handlers.c | 1 |
2 files changed, 104 insertions, 82 deletions
diff --git a/sway/config.c b/sway/config.c index c9a9cc74..b64dd4b1 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -11,22 +11,58 @@ | |||
11 | #include "layout.h" | 11 | #include "layout.h" |
12 | #include "input_state.h" | 12 | #include "input_state.h" |
13 | 13 | ||
14 | struct sway_config *config; | 14 | struct sway_config *config = NULL; |
15 | 15 | ||
16 | static bool exists(const char *path) { | 16 | static void free_variable(struct sway_variable *var) { |
17 | free(var->name); | ||
18 | free(var->value); | ||
19 | free(var); | ||
20 | } | ||
21 | |||
22 | static void free_binding(struct sway_binding *bind) { | ||
23 | free_flat_list(bind->keys); | ||
24 | free(bind->command); | ||
25 | free(bind); | ||
26 | } | ||
27 | |||
28 | static void free_mode(struct sway_mode *mode) { | ||
29 | free(mode->name); | ||
30 | int i; | ||
31 | for (i = 0; i < mode->bindings->length; ++i) { | ||
32 | free_binding(mode->bindings->items[i]); | ||
33 | } | ||
34 | list_free(mode->bindings); | ||
35 | free(mode); | ||
36 | } | ||
37 | |||
38 | static void free_outut_config(struct output_config *oc) { | ||
39 | free(oc->name); | ||
40 | free(oc); | ||
41 | } | ||
42 | |||
43 | static void free_workspace_output(struct workspace_output *wo) { | ||
44 | free(wo->output); | ||
45 | free(wo->workspace); | ||
46 | free(wo); | ||
47 | } | ||
48 | |||
49 | static bool file_exists(const char *path) { | ||
17 | return access(path, R_OK) != -1; | 50 | return access(path, R_OK) != -1; |
18 | } | 51 | } |
19 | 52 | ||
20 | void config_defaults(struct sway_config *config) { | 53 | static void config_defaults(struct sway_config *config) { |
21 | config->symbols = create_list(); | 54 | config->symbols = create_list(); |
22 | config->modes = create_list(); | 55 | config->modes = create_list(); |
23 | config->cmd_queue = create_list(); | ||
24 | config->workspace_outputs = create_list(); | 56 | config->workspace_outputs = create_list(); |
25 | config->output_configs = create_list(); | 57 | config->output_configs = create_list(); |
58 | |||
59 | config->cmd_queue = create_list(); | ||
60 | |||
26 | config->current_mode = malloc(sizeof(struct sway_mode)); | 61 | config->current_mode = malloc(sizeof(struct sway_mode)); |
27 | config->current_mode->name = NULL; | 62 | config->current_mode->name = NULL; |
28 | config->current_mode->bindings = create_list(); | 63 | config->current_mode->bindings = create_list(); |
29 | list_add(config->modes, config->current_mode); | 64 | list_add(config->modes, config->current_mode); |
65 | |||
30 | config->floating_mod = 0; | 66 | config->floating_mod = 0; |
31 | config->default_layout = L_NONE; | 67 | config->default_layout = L_NONE; |
32 | config->default_orientation = L_NONE; | 68 | config->default_orientation = L_NONE; |
@@ -42,115 +78,99 @@ void config_defaults(struct sway_config *config) { | |||
42 | config->gaps_outer = 0; | 78 | config->gaps_outer = 0; |
43 | } | 79 | } |
44 | 80 | ||
45 | void free_mode(struct sway_mode *mode) { | ||
46 | free(mode->name); | ||
47 | free_flat_list(mode->bindings); | ||
48 | } | ||
49 | |||
50 | void free_config(struct sway_config *config) { | 81 | void free_config(struct sway_config *config) { |
51 | int i; | 82 | int i; |
83 | for (i = 0; i < config->symbols->length; ++i) { | ||
84 | free_variable(config->symbols->items[i]); | ||
85 | } | ||
86 | list_free(config->symbols); | ||
87 | |||
52 | for (i = 0; i < config->modes->length; ++i) { | 88 | for (i = 0; i < config->modes->length; ++i) { |
53 | free_mode((struct sway_mode *)config->modes->items[i]); | 89 | free_mode(config->modes->items[i]); |
54 | } | 90 | } |
55 | free_flat_list(config->modes); | 91 | list_free(config->modes); |
92 | |||
93 | free_flat_list(config->cmd_queue); | ||
94 | |||
56 | for (i = 0; i < config->workspace_outputs->length; ++i) { | 95 | for (i = 0; i < config->workspace_outputs->length; ++i) { |
57 | struct workspace_output *wso = config->workspace_outputs->items[i]; | 96 | free_workspace_output(config->workspace_outputs->items[i]); |
58 | free(wso->output); | ||
59 | free(wso->workspace); | ||
60 | } | 97 | } |
61 | free_flat_list(config->workspace_outputs); | 98 | list_free(config->workspace_outputs); |
62 | free_flat_list(config->cmd_queue); | 99 | |
63 | for (i = 0; i < config->symbols->length; ++i) { | 100 | for (i = 0; i < config->output_configs->length; ++i) { |
64 | struct sway_variable *sym = config->symbols->items[i]; | 101 | free_outut_config(config->output_configs->items[i]); |
65 | free(sym->name); | ||
66 | free(sym->value); | ||
67 | } | 102 | } |
68 | free_flat_list(config->symbols); | 103 | list_free(config->output_configs); |
69 | free_flat_list(config->output_configs); | 104 | free(config); |
70 | } | 105 | } |
71 | 106 | ||
72 | static const char *search_paths[] = { | 107 | static char *get_config_path(void) { |
73 | "$home/.sway/config", | 108 | char *config_path = NULL; |
74 | "$config/sway/config", | 109 | char *paths[3] = {getenv("HOME"), getenv("XDG_CONFIG_HOME"), ""}; |
75 | "/etc/sway/config", | 110 | int pathlen[3] = {0, 0, 0}; |
76 | "$home/.i3/config", | 111 | int i; |
77 | "$config/.i3/config", | 112 | #define home paths[0] |
78 | "/etc/i3/config" | 113 | #define conf paths[1] |
79 | }; | 114 | // Get home and config directories |
80 | 115 | home = home ? strdup(home) : NULL; | |
81 | static char *get_config_path() { | 116 | if (conf) { |
82 | char *home = getenv("HOME"); | 117 | conf = strdup(conf); |
83 | if (home) { | ||
84 | home = strdup(getenv("HOME")); | ||
85 | } | ||
86 | char *config = getenv("XDG_CONFIG_HOME"); | ||
87 | if (config) { | ||
88 | config = strdup(getenv("XDG_CONFIG_HOME")); | ||
89 | } else if (home) { | 118 | } else if (home) { |
90 | const char *def = "/.config"; | 119 | const char *def = "/.config"; |
91 | config = malloc(strlen(home) + strlen(def) + 1); | 120 | conf = malloc(strlen(home) + strlen(def) + 1); |
92 | strcpy(config, home); | 121 | strcpy(conf, home); |
93 | strcat(config, def); | 122 | strcat(conf, def); |
94 | } else { | 123 | } else { |
95 | home = strdup(""); | 124 | home = strdup(""); |
96 | config = strdup(""); | 125 | conf = strdup(""); |
97 | } | 126 | } |
98 | 127 | pathlen[0] = strlen(home); | |
99 | // Set up a temporary config for holding set variables | 128 | pathlen[1] = strlen(conf); |
100 | struct sway_config *temp_config = malloc(sizeof(struct sway_config)); | 129 | #undef home |
101 | config_defaults(temp_config); | 130 | #undef conf |
102 | const char *set_home = "set $home "; | 131 | // Search for config file from search paths |
103 | char *_home = malloc(strlen(home) + strlen(set_home) + 1); | 132 | static const char *search_paths[] = { |
104 | strcpy(_home, set_home); | 133 | "/.sway/config", // Prepend with $home |
105 | strcat(_home, home); | 134 | "/sway/config", // Prepend with $config |
106 | handle_command(temp_config, _home); | 135 | "/etc/sway/config", |
107 | free(_home); | 136 | "/.i3/config", // $home |
108 | const char *set_config = "set $config "; | 137 | "/.i3/config", // $config |
109 | char *_config = malloc(strlen(config) + strlen(set_config) + 1); | 138 | "/etc/i3/config" |
110 | strcpy(_config, set_config); | 139 | }; |
111 | strcat(_config, config); | ||
112 | handle_command(temp_config, _config); | ||
113 | free(_config); | ||
114 | |||
115 | char *test = NULL; | ||
116 | int i; | ||
117 | for (i = 0; i < (int)(sizeof(search_paths) / sizeof(char *)); ++i) { | 140 | for (i = 0; i < (int)(sizeof(search_paths) / sizeof(char *)); ++i) { |
118 | test = strdup(search_paths[i]); | 141 | char *test = malloc(pathlen[i%3] + strlen(search_paths[i]) + 1); |
119 | test = do_var_replacement(temp_config, test); | 142 | strcpy(test, paths[i%3]); |
143 | strcat(test, search_paths[i]); | ||
120 | sway_log(L_DEBUG, "Checking for config at %s", test); | 144 | sway_log(L_DEBUG, "Checking for config at %s", test); |
121 | if (exists(test)) { | 145 | if (file_exists(test)) { |
122 | goto _continue; | 146 | config_path = test; |
147 | goto cleanup; | ||
123 | } | 148 | } |
124 | free(test); | 149 | free(test); |
125 | test = NULL; | ||
126 | } | 150 | } |
127 | 151 | ||
128 | sway_log(L_DEBUG, "Trying to find config in XDG_CONFIG_DIRS"); | 152 | sway_log(L_DEBUG, "Trying to find config in XDG_CONFIG_DIRS"); |
129 | char *xdg_config_dirs = getenv("XDG_CONFIG_DIRS"); | 153 | char *xdg_config_dirs = getenv("XDG_CONFIG_DIRS"); |
130 | if (xdg_config_dirs != NULL) { | 154 | if (xdg_config_dirs) { |
131 | list_t *paths = split_string(xdg_config_dirs, ":"); | 155 | list_t *paths = split_string(xdg_config_dirs, ":"); |
132 | char *name = "/sway/config"; | 156 | const char *name = "/sway/config"; |
133 | int i; | ||
134 | for (i = 0; i < paths->length; i++ ) { | 157 | for (i = 0; i < paths->length; i++ ) { |
135 | test = malloc(strlen(paths->items[i]) + strlen(name) + 1); | 158 | char *test = malloc(strlen(paths->items[i]) + strlen(name) + 1); |
136 | strcpy(test, paths->items[i]); | 159 | strcpy(test, paths->items[i]); |
137 | strcat(test, name); | 160 | strcat(test, name); |
138 | if (exists(test)) { | 161 | if (file_exists(test)) { |
139 | free_config(temp_config); | 162 | config_path = test; |
140 | free_flat_list(paths); | 163 | break; |
141 | return test; | ||
142 | } | 164 | } |
143 | free(test); | 165 | free(test); |
144 | test = NULL; | ||
145 | } | 166 | } |
146 | free_flat_list(paths); | 167 | free_flat_list(paths); |
147 | } | 168 | } |
148 | 169 | ||
149 | _continue: | 170 | cleanup: |
150 | free_config(temp_config); | 171 | free(paths[0]); |
151 | free(home); | 172 | free(paths[1]); |
152 | free(config); | 173 | return config_path; |
153 | return test; | ||
154 | } | 174 | } |
155 | 175 | ||
156 | bool load_config(const char *file) { | 176 | bool load_config(const char *file) { |
@@ -248,6 +268,9 @@ _continue: | |||
248 | temp_config->reloading = false; | 268 | temp_config->reloading = false; |
249 | arrange_windows(&root_container, -1, -1); | 269 | arrange_windows(&root_container, -1, -1); |
250 | } | 270 | } |
271 | if (config) { | ||
272 | free_config(config); | ||
273 | } | ||
251 | config = temp_config; | 274 | config = temp_config; |
252 | 275 | ||
253 | return success; | 276 | return success; |
diff --git a/sway/handlers.c b/sway/handlers.c index 413c17fe..482d52c6 100644 --- a/sway/handlers.c +++ b/sway/handlers.c | |||
@@ -334,7 +334,6 @@ static bool handle_key(wlc_handle view, uint32_t time, const struct wlc_modifier | |||
334 | release_key(sym, key); | 334 | release_key(sym, key); |
335 | } | 335 | } |
336 | 336 | ||
337 | // TODO: reminder to check conflicts with mod+q+a versus mod+q | ||
338 | for (i = 0; i < mode->bindings->length; ++i) { | 337 | for (i = 0; i < mode->bindings->length; ++i) { |
339 | struct sway_binding *binding = mode->bindings->items[i]; | 338 | struct sway_binding *binding = mode->bindings->items[i]; |
340 | 339 | ||