summaryrefslogtreecommitdiffstats
path: root/sway/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/config.c')
-rw-r--r--sway/config.c151
1 files changed, 121 insertions, 30 deletions
diff --git a/sway/config.c b/sway/config.c
index a5fdf850..d54ce213 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -2,6 +2,7 @@
2#include <stdbool.h> 2#include <stdbool.h>
3#include <stdlib.h> 3#include <stdlib.h>
4#include <unistd.h> 4#include <unistd.h>
5#include <libgen.h>
5#include <wordexp.h> 6#include <wordexp.h>
6#include <sys/types.h> 7#include <sys/types.h>
7#include <sys/wait.h> 8#include <sys/wait.h>
@@ -126,6 +127,7 @@ void free_config(struct sway_config *config) {
126 list_free(config->output_configs); 127 list_free(config->output_configs);
127 128
128 list_free(config->active_bar_modifiers); 129 list_free(config->active_bar_modifiers);
130 free_flat_list(config->config_chain);
129 free(config->font); 131 free(config->font);
130 free(config); 132 free(config);
131} 133}
@@ -175,6 +177,9 @@ static void config_defaults(struct sway_config *config) {
175 config->gaps_outer = 0; 177 config->gaps_outer = 0;
176 178
177 config->active_bar_modifiers = create_list(); 179 config->active_bar_modifiers = create_list();
180
181 config->config_chain = create_list();
182 config->current_config = NULL;
178} 183}
179 184
180static int compare_modifiers(const void *left, const void *right) { 185static int compare_modifiers(const void *left, const void *right) {
@@ -237,16 +242,7 @@ static char *get_config_path(void) {
237 return NULL; // Not reached 242 return NULL; // Not reached
238} 243}
239 244
240bool load_config(const char *file) { 245static bool load_config(const char *path, struct sway_config *config) {
241 input_init();
242
243 char *path;
244 if (file != NULL) {
245 path = strdup(file);
246 } else {
247 path = get_config_path();
248 }
249
250 sway_log(L_INFO, "Loading config from %s", path); 246 sway_log(L_INFO, "Loading config from %s", path);
251 247
252 if (path == NULL) { 248 if (path == NULL) {
@@ -257,20 +253,12 @@ bool load_config(const char *file) {
257 FILE *f = fopen(path, "r"); 253 FILE *f = fopen(path, "r");
258 if (!f) { 254 if (!f) {
259 sway_log(L_ERROR, "Unable to open %s for reading", path); 255 sway_log(L_ERROR, "Unable to open %s for reading", path);
260 free(path);
261 return false; 256 return false;
262 } 257 }
263 free(path);
264 258
265 bool config_load_success; 259 bool config_load_success = read_config(f, config);
266 if (config) {
267 config_load_success = read_config(f, true);
268 } else {
269 config_load_success = read_config(f, false);
270 }
271 fclose(f); 260 fclose(f);
272 261
273 update_active_bar_modifiers();
274 262
275 if (!config_load_success) { 263 if (!config_load_success) {
276 sway_log(L_ERROR, "Error(s) loading config!"); 264 sway_log(L_ERROR, "Error(s) loading config!");
@@ -279,17 +267,129 @@ bool load_config(const char *file) {
279 return true; 267 return true;
280} 268}
281 269
282bool read_config(FILE *file, bool is_active) { 270bool load_main_config(const char *file, bool is_active) {
271 input_init();
272
273 char *path;
274 if (file != NULL) {
275 path = strdup(file);
276 } else {
277 path = get_config_path();
278 }
279
283 struct sway_config *old_config = config; 280 struct sway_config *old_config = config;
284 config = calloc(1, sizeof(struct sway_config)); 281 config = calloc(1, sizeof(struct sway_config));
285 282
286 config_defaults(config); 283 config_defaults(config);
287 config->reading = true;
288 if (is_active) { 284 if (is_active) {
289 sway_log(L_DEBUG, "Performing configuration file reload"); 285 sway_log(L_DEBUG, "Performing configuration file reload");
290 config->reloading = true; 286 config->reloading = true;
291 config->active = true; 287 config->active = true;
292 } 288 }
289
290 config->current_config = path;
291 list_add(config->config_chain, path);
292
293 config->reading = true;
294 bool success = load_config(path, config);
295
296 if (is_active) {
297 config->reloading = false;
298 }
299
300 if (old_config) {
301 free_config(old_config);
302 }
303 config->reading = false;
304
305 if (success) {
306 update_active_bar_modifiers();
307 }
308
309 return success;
310}
311
312static bool load_include_config(const char *path, const char *parent_dir, struct sway_config *config) {
313 // save parent config
314 const char *parent_config = config->current_config;
315
316 char *full_path = strdup(path);
317 int len = strlen(path);
318 if (len >= 1 && path[0] != '/') {
319 len = len + strlen(parent_dir) + 2;
320 full_path = malloc(len * sizeof(char));
321 snprintf(full_path, len, "%s/%s", parent_dir, path);
322 }
323
324 char *real_path = realpath(full_path, NULL);
325 free(full_path);
326
327 // check if config has already been included
328 int j;
329 for (j = 0; j < config->config_chain->length; ++j) {
330 char *old_path = config->config_chain->items[j];
331 if (strcmp(real_path, old_path) == 0) {
332 sway_log(L_DEBUG, "%s already included once, won't be included again.", real_path);
333 free(real_path);
334 return false;
335 }
336 }
337
338 config->current_config = real_path;
339 list_add(config->config_chain, real_path);
340 int index = config->config_chain->length - 1;
341
342 if (!load_config(real_path, config)) {
343 free(real_path);
344 config->current_config = parent_config;
345 list_del(config->config_chain, index);
346 return false;
347 }
348
349 // restore current_config
350 config->current_config = parent_config;
351 return true;
352}
353
354bool load_include_configs(const char *path, struct sway_config *config) {
355 char *wd = getcwd(NULL, 0);
356 char *parent_path = strdup(config->current_config);
357 const char *parent_dir = dirname(parent_path);
358
359 if (chdir(parent_dir) < 0) {
360 free(parent_path);
361 free(wd);
362 return false;
363 }
364
365 wordexp_t p;
366
367 if (wordexp(path, &p, 0) < 0) {
368 free(parent_path);
369 free(wd);
370 return false;
371 }
372
373 char **w = p.we_wordv;
374 size_t i;
375 for (i = 0; i < p.we_wordc; ++i) {
376 load_include_config(w[i], parent_dir, config);
377 }
378 free(parent_path);
379 wordfree(&p);
380
381 // restore wd
382 if (chdir(wd) < 0) {
383 free(wd);
384 sway_log(L_ERROR, "failed to restore working directory");
385 return false;
386 }
387
388 free(wd);
389 return true;
390}
391
392bool read_config(FILE *file, struct sway_config *config) {
293 bool success = true; 393 bool success = true;
294 enum cmd_status block = CMD_BLOCK_END; 394 enum cmd_status block = CMD_BLOCK_END;
295 395
@@ -386,15 +486,6 @@ bool read_config(FILE *file, bool is_active) {
386 free(res); 486 free(res);
387 } 487 }
388 488
389 if (is_active) {
390 config->reloading = false;
391 arrange_windows(&root_container, -1, -1);
392 }
393 if (old_config) {
394 free_config(old_config);
395 }
396
397 config->reading = false;
398 return success; 489 return success;
399} 490}
400 491