aboutsummaryrefslogtreecommitdiffstats
path: root/sway/config.c
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-08-02 21:37:29 -0400
committerLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-08-03 10:37:35 -0400
commita7f7d4a488c8d3b2461122765f9904c8a411a583 (patch)
tree7abee51265a8b9550c62255d0c6649935ee1d6a2 /sway/config.c
parentShow swaynag on config errors (diff)
downloadsway-a7f7d4a488c8d3b2461122765f9904c8a411a583.tar.gz
sway-a7f7d4a488c8d3b2461122765f9904c8a411a583.tar.zst
sway-a7f7d4a488c8d3b2461122765f9904c8a411a583.zip
Write to swaynag pipe fd directly on config errors
Diffstat (limited to 'sway/config.c')
-rw-r--r--sway/config.c104
1 files changed, 40 insertions, 64 deletions
diff --git a/sway/config.c b/sway/config.c
index bd282541..4464b006 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -25,6 +25,7 @@
25#include "sway/commands.h" 25#include "sway/commands.h"
26#include "sway/config.h" 26#include "sway/config.h"
27#include "sway/criteria.h" 27#include "sway/criteria.h"
28#include "sway/swaynag.h"
28#include "sway/tree/arrange.h" 29#include "sway/tree/arrange.h"
29#include "sway/tree/layout.h" 30#include "sway/tree/layout.h"
30#include "sway/tree/workspace.h" 31#include "sway/tree/workspace.h"
@@ -72,6 +73,8 @@ void free_config(struct sway_config *config) {
72 73
73 memset(&config->handler_context, 0, sizeof(config->handler_context)); 74 memset(&config->handler_context, 0, sizeof(config->handler_context));
74 75
76 free(config->swaynag_command);
77
75 // TODO: handle all currently unhandled lists as we add implementations 78 // TODO: handle all currently unhandled lists as we add implementations
76 if (config->symbols) { 79 if (config->symbols) {
77 for (int i = 0; i < config->symbols->length; ++i) { 80 for (int i = 0; i < config->symbols->length; ++i) {
@@ -158,7 +161,17 @@ static void set_color(float dest[static 4], uint32_t color) {
158} 161}
159 162
160static void config_defaults(struct sway_config *config) { 163static void config_defaults(struct sway_config *config) {
161 config->swaynag_pid = -1; 164 config->swaynag_command = strdup("swaynag");
165 config->swaynag_config_errors = (struct swaynag_instance){
166 .args = "--type error "
167 "--message 'There are errors in your config file' "
168 "--detailed-message "
169 "--button 'Exit sway' 'swaymsg exit' "
170 "--button 'Reload sway' 'swaymsg reload'",
171 .pid = -1,
172 .detailed = true,
173 };
174
162 if (!(config->symbols = create_list())) goto cleanup; 175 if (!(config->symbols = create_list())) goto cleanup;
163 if (!(config->modes = create_list())) goto cleanup; 176 if (!(config->modes = create_list())) goto cleanup;
164 if (!(config->bars = create_list())) goto cleanup; 177 if (!(config->bars = create_list())) goto cleanup;
@@ -205,6 +218,7 @@ static void config_defaults(struct sway_config *config) {
205 config->focus_follows_mouse = true; 218 config->focus_follows_mouse = true;
206 config->mouse_warping = true; 219 config->mouse_warping = true;
207 config->focus_wrapping = WRAP_YES; 220 config->focus_wrapping = WRAP_YES;
221 config->validating = false;
208 config->reloading = false; 222 config->reloading = false;
209 config->active = false; 223 config->active = false;
210 config->failed = false; 224 config->failed = false;
@@ -321,7 +335,7 @@ static char *get_config_path(void) {
321} 335}
322 336
323static bool load_config(const char *path, struct sway_config *config, 337static bool load_config(const char *path, struct sway_config *config,
324 char **errors) { 338 struct swaynag_instance *swaynag) {
325 if (path == NULL) { 339 if (path == NULL) {
326 wlr_log(WLR_ERROR, "Unable to find a config file!"); 340 wlr_log(WLR_ERROR, "Unable to find a config file!");
327 return false; 341 return false;
@@ -340,7 +354,7 @@ static bool load_config(const char *path, struct sway_config *config,
340 return false; 354 return false;
341 } 355 }
342 356
343 bool config_load_success = read_config(f, config, errors); 357 bool config_load_success = read_config(f, config, swaynag);
344 fclose(f); 358 fclose(f);
345 359
346 if (!config_load_success) { 360 if (!config_load_success) {
@@ -350,7 +364,7 @@ static bool load_config(const char *path, struct sway_config *config,
350 return true; 364 return true;
351} 365}
352 366
353bool load_main_config(const char *file, bool is_active, char **errors) { 367bool load_main_config(const char *file, bool is_active, bool validating) {
354 char *path; 368 char *path;
355 if (file != NULL) { 369 if (file != NULL) {
356 path = strdup(file); 370 path = strdup(file);
@@ -365,11 +379,16 @@ bool load_main_config(const char *file, bool is_active, char **errors) {
365 } 379 }
366 380
367 config_defaults(config); 381 config_defaults(config);
382 config->validating = validating;
368 if (is_active) { 383 if (is_active) {
369 wlr_log(WLR_DEBUG, "Performing configuration file reload"); 384 wlr_log(WLR_DEBUG, "Performing configuration file reload");
370 config->swaynag_pid = old_config->swaynag_pid;
371 config->reloading = true; 385 config->reloading = true;
372 config->active = true; 386 config->active = true;
387
388 swaynag_kill(&old_config->swaynag_config_errors);
389 swaynag_clone(&config->swaynag_config_errors,
390 &old_config->swaynag_config_errors);
391
373 create_default_output_configs(); 392 create_default_output_configs();
374 } 393 }
375 394
@@ -426,13 +445,17 @@ bool load_main_config(const char *file, bool is_active, char **errors) {
426 } 445 }
427 */ 446 */
428 447
429 success = success && load_config(path, config, errors); 448 success = success && load_config(path, config,
449 &config->swaynag_config_errors);
430 450
431 if (is_active) { 451 if (is_active) {
432 for (int i = 0; i < config->output_configs->length; i++) { 452 for (int i = 0; i < config->output_configs->length; i++) {
433 apply_output_config_to_outputs(config->output_configs->items[i]); 453 apply_output_config_to_outputs(config->output_configs->items[i]);
434 } 454 }
435 config->reloading = false; 455 config->reloading = false;
456 if (config->swaynag_config_errors.pid > 0) {
457 swaynag_show(&config->swaynag_config_errors);
458 }
436 } 459 }
437 460
438 if (old_config) { 461 if (old_config) {
@@ -444,7 +467,7 @@ bool load_main_config(const char *file, bool is_active, char **errors) {
444} 467}
445 468
446static bool load_include_config(const char *path, const char *parent_dir, 469static bool load_include_config(const char *path, const char *parent_dir,
447 struct sway_config *config, char **errors) { 470 struct sway_config *config, struct swaynag_instance *swaynag) {
448 // save parent config 471 // save parent config
449 const char *parent_config = config->current_config_path; 472 const char *parent_config = config->current_config_path;
450 473
@@ -488,7 +511,7 @@ static bool load_include_config(const char *path, const char *parent_dir,
488 list_add(config->config_chain, real_path); 511 list_add(config->config_chain, real_path);
489 int index = config->config_chain->length - 1; 512 int index = config->config_chain->length - 1;
490 513
491 if (!load_config(real_path, config, errors)) { 514 if (!load_config(real_path, config, swaynag)) {
492 free(real_path); 515 free(real_path);
493 config->current_config_path = parent_config; 516 config->current_config_path = parent_config;
494 list_del(config->config_chain, index); 517 list_del(config->config_chain, index);
@@ -501,7 +524,7 @@ static bool load_include_config(const char *path, const char *parent_dir,
501} 524}
502 525
503bool load_include_configs(const char *path, struct sway_config *config, 526bool load_include_configs(const char *path, struct sway_config *config,
504 char **errors) { 527 struct swaynag_instance *swaynag) {
505 char *wd = getcwd(NULL, 0); 528 char *wd = getcwd(NULL, 0);
506 char *parent_path = strdup(config->current_config_path); 529 char *parent_path = strdup(config->current_config_path);
507 const char *parent_dir = dirname(parent_path); 530 const char *parent_dir = dirname(parent_path);
@@ -523,7 +546,7 @@ bool load_include_configs(const char *path, struct sway_config *config,
523 char **w = p.we_wordv; 546 char **w = p.we_wordv;
524 size_t i; 547 size_t i;
525 for (i = 0; i < p.we_wordc; ++i) { 548 for (i = 0; i < p.we_wordc; ++i) {
526 load_include_config(w[i], parent_dir, config, errors); 549 load_include_config(w[i], parent_dir, config, swaynag);
527 } 550 }
528 free(parent_path); 551 free(parent_path);
529 wordfree(&p); 552 wordfree(&p);
@@ -579,26 +602,8 @@ static char *expand_line(const char *block, const char *line, bool add_brace) {
579 return expanded; 602 return expanded;
580} 603}
581 604
582static void log_error(char **errors, const char *fmt, ...) { 605bool read_config(FILE *file, struct sway_config *config,
583 va_list args; 606 struct swaynag_instance *swaynag) {
584 va_start(args, fmt);
585 size_t length = vsnprintf(NULL, 0, fmt, args) + 1;
586 va_end(args);
587
588 int offset = *errors ? strlen(*errors) : 0;
589 char *temp = realloc(*errors, offset + length + 1);
590 if (!temp) {
591 wlr_log(WLR_ERROR, "Failed to realloc error log");
592 return;
593 }
594 *errors = temp;
595
596 va_start(args, fmt);
597 vsnprintf(*errors + offset, length, fmt, args);
598 va_end(args);
599}
600
601bool read_config(FILE *file, struct sway_config *config, char **errors) {
602 bool reading_main_config = false; 607 bool reading_main_config = false;
603 char *this_config = NULL; 608 char *this_config = NULL;
604 size_t config_size = 0; 609 size_t config_size = 0;
@@ -688,8 +693,11 @@ bool read_config(FILE *file, struct sway_config *config, char **errors) {
688 case CMD_INVALID: 693 case CMD_INVALID:
689 wlr_log(WLR_ERROR, "Error on line %i '%s': %s (%s)", line_number, 694 wlr_log(WLR_ERROR, "Error on line %i '%s': %s (%s)", line_number,
690 line, res->error, config->current_config_path); 695 line, res->error, config->current_config_path);
691 log_error(errors, "Error on line %i (%s) '%s': %s\n", line_number, 696 if (!config->validating) {
692 config->current_config_path, line, res->error); 697 swaynag_log(config->swaynag_command, swaynag,
698 "Error on line %i (%s) '%s': %s", line_number,
699 config->current_config_path, line, res->error);
700 }
693 success = false; 701 success = false;
694 break; 702 break;
695 703
@@ -738,38 +746,6 @@ bool read_config(FILE *file, struct sway_config *config, char **errors) {
738 return success; 746 return success;
739} 747}
740 748
741void spawn_swaynag_config_errors(struct sway_config *config, char *errors) {
742 char *command = "swaynag "
743 "--type error "
744 "--message 'There are errors in your config file' "
745 "--detailed-message "
746 "--button 'Exit sway' 'swaymsg exit' "
747 "--button 'Reload sway' 'swaymsg reload'";
748
749 int fd[2];
750 if (pipe(fd) != 0) {
751 wlr_log(WLR_ERROR, "Failed to create pipe for swaynag");
752 return;
753 }
754
755 pid_t pid;
756 if ((pid = fork()) == 0) {
757 close(fd[1]);
758 dup2(fd[0], STDIN_FILENO);
759 close(fd[0]);
760 execl("/bin/sh", "/bin/sh", "-c", command, NULL);
761 _exit(0);
762 } else if (pid < 0) {
763 wlr_log(WLR_ERROR, "Failed to create fork for swaynag");
764 }
765
766 close(fd[0]);
767 write(fd[1], errors, strlen(errors));
768 close(fd[1]);
769
770 config->swaynag_pid = pid;
771}
772
773char *do_var_replacement(char *str) { 749char *do_var_replacement(char *str) {
774 int i; 750 int i;
775 char *find = str; 751 char *find = str;