diff options
Diffstat (limited to 'sway/config.c')
-rw-r--r-- | sway/config.c | 121 |
1 files changed, 41 insertions, 80 deletions
diff --git a/sway/config.c b/sway/config.c index b41dd871..f9131e0f 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #undef _POSIX_C_SOURCE | ||
1 | #define _XOPEN_SOURCE 700 // for realpath | 2 | #define _XOPEN_SOURCE 700 // for realpath |
2 | #include <stdio.h> | 3 | #include <stdio.h> |
3 | #include <stdbool.h> | 4 | #include <stdbool.h> |
@@ -36,19 +37,26 @@ | |||
36 | struct sway_config *config = NULL; | 37 | struct sway_config *config = NULL; |
37 | 38 | ||
38 | static struct xkb_state *keysym_translation_state_create( | 39 | static struct xkb_state *keysym_translation_state_create( |
39 | struct xkb_rule_names rules) { | 40 | struct xkb_rule_names rules, uint32_t context_flags) { |
40 | struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); | 41 | struct xkb_context *context = xkb_context_new(context_flags | XKB_CONTEXT_NO_SECURE_GETENV); |
41 | struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_names( | 42 | struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_names( |
42 | context, | 43 | context, |
43 | &rules, | 44 | &rules, |
44 | XKB_KEYMAP_COMPILE_NO_FLAGS); | 45 | XKB_KEYMAP_COMPILE_NO_FLAGS); |
45 | |||
46 | xkb_context_unref(context); | 46 | xkb_context_unref(context); |
47 | if (xkb_keymap == NULL) { | ||
48 | sway_log(SWAY_ERROR, "Failed to compile keysym translation XKB keymap"); | ||
49 | return NULL; | ||
50 | } | ||
51 | |||
47 | return xkb_state_new(xkb_keymap); | 52 | return xkb_state_new(xkb_keymap); |
48 | } | 53 | } |
49 | 54 | ||
50 | static void keysym_translation_state_destroy( | 55 | static void keysym_translation_state_destroy( |
51 | struct xkb_state *state) { | 56 | struct xkb_state *state) { |
57 | if (state == NULL) { | ||
58 | return; | ||
59 | } | ||
52 | xkb_keymap_unref(xkb_state_get_keymap(state)); | 60 | xkb_keymap_unref(xkb_state_get_keymap(state)); |
53 | xkb_state_unref(state); | 61 | xkb_state_unref(state); |
54 | } | 62 | } |
@@ -273,6 +281,7 @@ static void config_defaults(struct sway_config *config) { | |||
273 | config->title_align = ALIGN_LEFT; | 281 | config->title_align = ALIGN_LEFT; |
274 | config->tiling_drag = true; | 282 | config->tiling_drag = true; |
275 | config->tiling_drag_threshold = 9; | 283 | config->tiling_drag_threshold = 9; |
284 | config->primary_selection = true; | ||
276 | 285 | ||
277 | config->smart_gaps = SMART_GAPS_OFF; | 286 | config->smart_gaps = SMART_GAPS_OFF; |
278 | config->gaps_inner = 0; | 287 | config->gaps_inner = 0; |
@@ -335,8 +344,14 @@ static void config_defaults(struct sway_config *config) { | |||
335 | 344 | ||
336 | // The keysym to keycode translation | 345 | // The keysym to keycode translation |
337 | struct xkb_rule_names rules = {0}; | 346 | struct xkb_rule_names rules = {0}; |
338 | config->keysym_translation_state = | 347 | config->keysym_translation_state = keysym_translation_state_create(rules, 0); |
339 | keysym_translation_state_create(rules); | 348 | if (config->keysym_translation_state == NULL) { |
349 | config->keysym_translation_state = keysym_translation_state_create(rules, | ||
350 | XKB_CONTEXT_NO_ENVIRONMENT_NAMES); | ||
351 | } | ||
352 | if (config->keysym_translation_state == NULL) { | ||
353 | goto cleanup; | ||
354 | } | ||
340 | 355 | ||
341 | return; | 356 | return; |
342 | cleanup: | 357 | cleanup: |
@@ -351,13 +366,7 @@ static char *config_path(const char *prefix, const char *config_folder) { | |||
351 | if (!prefix || !prefix[0] || !config_folder || !config_folder[0]) { | 366 | if (!prefix || !prefix[0] || !config_folder || !config_folder[0]) { |
352 | return NULL; | 367 | return NULL; |
353 | } | 368 | } |
354 | 369 | return format_str("%s/%s/config", prefix, config_folder); | |
355 | const char *filename = "config"; | ||
356 | |||
357 | size_t size = 3 + strlen(prefix) + strlen(config_folder) + strlen(filename); | ||
358 | char *path = calloc(size, sizeof(char)); | ||
359 | snprintf(path, size, "%s/%s/%s", prefix, config_folder, filename); | ||
360 | return path; | ||
361 | } | 370 | } |
362 | 371 | ||
363 | static char *get_config_path(void) { | 372 | static char *get_config_path(void) { |
@@ -367,10 +376,7 @@ static char *get_config_path(void) { | |||
367 | 376 | ||
368 | const char *config_home = getenv("XDG_CONFIG_HOME"); | 377 | const char *config_home = getenv("XDG_CONFIG_HOME"); |
369 | if ((config_home == NULL || config_home[0] == '\0') && home != NULL) { | 378 | if ((config_home == NULL || config_home[0] == '\0') && home != NULL) { |
370 | size_t size_fallback = 1 + strlen(home) + strlen("/.config"); | 379 | config_home_fallback = format_str("%s/.config", home); |
371 | config_home_fallback = calloc(size_fallback, sizeof(char)); | ||
372 | if (config_home_fallback != NULL) | ||
373 | snprintf(config_home_fallback, size_fallback, "%s/.config", home); | ||
374 | config_home = config_home_fallback; | 380 | config_home = config_home_fallback; |
375 | } | 381 | } |
376 | 382 | ||
@@ -474,6 +480,11 @@ bool load_main_config(const char *file, bool is_active, bool validating) { | |||
474 | old_config->xwayland ? "enabled" : "disabled"); | 480 | old_config->xwayland ? "enabled" : "disabled"); |
475 | config->xwayland = old_config->xwayland; | 481 | config->xwayland = old_config->xwayland; |
476 | 482 | ||
483 | // primary_selection can only be enabled/disabled at launch | ||
484 | sway_log(SWAY_DEBUG, "primary_selection will remain %s", | ||
485 | old_config->primary_selection ? "enabled" : "disabled"); | ||
486 | config->primary_selection = old_config->primary_selection; | ||
487 | |||
477 | if (!config->validating) { | 488 | if (!config->validating) { |
478 | if (old_config->swaybg_client != NULL) { | 489 | if (old_config->swaybg_client != NULL) { |
479 | wl_client_destroy(old_config->swaybg_client); | 490 | wl_client_destroy(old_config->swaybg_client); |
@@ -493,56 +504,7 @@ bool load_main_config(const char *file, bool is_active, bool validating) { | |||
493 | 504 | ||
494 | config->reading = true; | 505 | config->reading = true; |
495 | 506 | ||
496 | // Read security configs | 507 | bool success = load_config(path, config, &config->swaynag_config_errors); |
497 | // TODO: Security | ||
498 | bool success = true; | ||
499 | /* | ||
500 | DIR *dir = opendir(SYSCONFDIR "/sway/security.d"); | ||
501 | if (!dir) { | ||
502 | sway_log(SWAY_ERROR, | ||
503 | "%s does not exist, sway will have no security configuration" | ||
504 | " and will probably be broken", SYSCONFDIR "/sway/security.d"); | ||
505 | } else { | ||
506 | list_t *secconfigs = create_list(); | ||
507 | char *base = SYSCONFDIR "/sway/security.d/"; | ||
508 | struct dirent *ent = readdir(dir); | ||
509 | struct stat s; | ||
510 | while (ent != NULL) { | ||
511 | char *_path = malloc(strlen(ent->d_name) + strlen(base) + 1); | ||
512 | strcpy(_path, base); | ||
513 | strcat(_path, ent->d_name); | ||
514 | lstat(_path, &s); | ||
515 | if (S_ISREG(s.st_mode) && ent->d_name[0] != '.') { | ||
516 | list_add(secconfigs, _path); | ||
517 | } | ||
518 | else { | ||
519 | free(_path); | ||
520 | } | ||
521 | ent = readdir(dir); | ||
522 | } | ||
523 | closedir(dir); | ||
524 | |||
525 | list_qsort(secconfigs, qstrcmp); | ||
526 | for (int i = 0; i < secconfigs->length; ++i) { | ||
527 | char *_path = secconfigs->items[i]; | ||
528 | if (stat(_path, &s) || s.st_uid != 0 || s.st_gid != 0 || | ||
529 | (((s.st_mode & 0777) != 0644) && | ||
530 | (s.st_mode & 0777) != 0444)) { | ||
531 | sway_log(SWAY_ERROR, | ||
532 | "Refusing to load %s - it must be owned by root " | ||
533 | "and mode 644 or 444", _path); | ||
534 | success = false; | ||
535 | } else { | ||
536 | success = success && load_config(_path, config); | ||
537 | } | ||
538 | } | ||
539 | |||
540 | list_free_items_and_destroy(secconfigs); | ||
541 | } | ||
542 | */ | ||
543 | |||
544 | success = success && load_config(path, config, | ||
545 | &config->swaynag_config_errors); | ||
546 | 508 | ||
547 | if (validating) { | 509 | if (validating) { |
548 | free_config(config); | 510 | free_config(config); |
@@ -570,7 +532,7 @@ bool load_main_config(const char *file, bool is_active, bool validating) { | |||
570 | } | 532 | } |
571 | sway_switch_retrigger_bindings_for_all(); | 533 | sway_switch_retrigger_bindings_for_all(); |
572 | 534 | ||
573 | reset_outputs(); | 535 | apply_all_output_configs(); |
574 | spawn_swaybg(); | 536 | spawn_swaybg(); |
575 | 537 | ||
576 | config->reloading = false; | 538 | config->reloading = false; |
@@ -923,23 +885,18 @@ void config_add_swaynag_warning(char *fmt, ...) { | |||
923 | if (config->reading && !config->validating) { | 885 | if (config->reading && !config->validating) { |
924 | va_list args; | 886 | va_list args; |
925 | va_start(args, fmt); | 887 | va_start(args, fmt); |
926 | size_t length = vsnprintf(NULL, 0, fmt, args) + 1; | 888 | char *str = vformat_str(fmt, args); |
927 | va_end(args); | 889 | va_end(args); |
928 | 890 | if (str == NULL) { | |
929 | char *temp = malloc(length + 1); | ||
930 | if (!temp) { | ||
931 | sway_log(SWAY_ERROR, "Failed to allocate buffer for warning."); | ||
932 | return; | 891 | return; |
933 | } | 892 | } |
934 | 893 | ||
935 | va_start(args, fmt); | ||
936 | vsnprintf(temp, length, fmt, args); | ||
937 | va_end(args); | ||
938 | |||
939 | swaynag_log(config->swaynag_command, &config->swaynag_config_errors, | 894 | swaynag_log(config->swaynag_command, &config->swaynag_config_errors, |
940 | "Warning on line %i (%s) '%s': %s", | 895 | "Warning on line %i (%s) '%s': %s", |
941 | config->current_config_line_number, config->current_config_path, | 896 | config->current_config_line_number, config->current_config_path, |
942 | config->current_config_line, temp); | 897 | config->current_config_line, str); |
898 | |||
899 | free(str); | ||
943 | } | 900 | } |
944 | } | 901 | } |
945 | 902 | ||
@@ -979,7 +936,7 @@ char *do_var_replacement(char *str) { | |||
979 | int offset = find - str; | 936 | int offset = find - str; |
980 | strncpy(newptr, str, offset); | 937 | strncpy(newptr, str, offset); |
981 | newptr += offset; | 938 | newptr += offset; |
982 | strncpy(newptr, var->value, vvlen); | 939 | memcpy(newptr, var->value, vvlen); |
983 | newptr += vvlen; | 940 | newptr += vvlen; |
984 | strcpy(newptr, find + vnlen); | 941 | strcpy(newptr, find + vnlen); |
985 | free(str); | 942 | free(str); |
@@ -1041,8 +998,12 @@ void translate_keysyms(struct input_config *input_config) { | |||
1041 | 998 | ||
1042 | struct xkb_rule_names rules = {0}; | 999 | struct xkb_rule_names rules = {0}; |
1043 | input_config_fill_rule_names(input_config, &rules); | 1000 | input_config_fill_rule_names(input_config, &rules); |
1044 | config->keysym_translation_state = | 1001 | config->keysym_translation_state = keysym_translation_state_create(rules, 0); |
1045 | keysym_translation_state_create(rules); | 1002 | if (config->keysym_translation_state == NULL) { |
1003 | sway_log(SWAY_ERROR, "Failed to create keysym translation XKB state " | ||
1004 | "for device '%s'", input_config->identifier); | ||
1005 | return; | ||
1006 | } | ||
1046 | 1007 | ||
1047 | for (int i = 0; i < config->modes->length; ++i) { | 1008 | for (int i = 0; i < config->modes->length; ++i) { |
1048 | struct sway_mode *mode = config->modes->items[i]; | 1009 | struct sway_mode *mode = config->modes->items[i]; |