aboutsummaryrefslogtreecommitdiffstats
path: root/sway/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/config.c')
-rw-r--r--sway/config.c135
1 files changed, 75 insertions, 60 deletions
diff --git a/sway/config.c b/sway/config.c
index 6e665434..4b51dc73 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -26,7 +26,7 @@
26#include "sway/tree/arrange.h" 26#include "sway/tree/arrange.h"
27#include "sway/tree/root.h" 27#include "sway/tree/root.h"
28#include "sway/tree/workspace.h" 28#include "sway/tree/workspace.h"
29#include "cairo.h" 29#include "cairo_util.h"
30#include "pango.h" 30#include "pango.h"
31#include "stringop.h" 31#include "stringop.h"
32#include "list.h" 32#include "list.h"
@@ -37,7 +37,7 @@ struct sway_config *config = NULL;
37 37
38static struct xkb_state *keysym_translation_state_create( 38static struct xkb_state *keysym_translation_state_create(
39 struct xkb_rule_names rules) { 39 struct xkb_rule_names rules) {
40 struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS); 40 struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_SECURE_GETENV);
41 struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_names( 41 struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_names(
42 context, 42 context,
43 &rules, 43 &rules,
@@ -82,6 +82,12 @@ static void free_mode(struct sway_mode *mode) {
82 } 82 }
83 list_free(mode->switch_bindings); 83 list_free(mode->switch_bindings);
84 } 84 }
85 if (mode->gesture_bindings) {
86 for (int i = 0; i < mode->gesture_bindings->length; i++) {
87 free_gesture_binding(mode->gesture_bindings->items[i]);
88 }
89 list_free(mode->gesture_bindings);
90 }
85 free(mode); 91 free(mode);
86} 92}
87 93
@@ -222,6 +228,7 @@ static void config_defaults(struct sway_config *config) {
222 if (!(config->current_mode->keycode_bindings = create_list())) goto cleanup; 228 if (!(config->current_mode->keycode_bindings = create_list())) goto cleanup;
223 if (!(config->current_mode->mouse_bindings = create_list())) goto cleanup; 229 if (!(config->current_mode->mouse_bindings = create_list())) goto cleanup;
224 if (!(config->current_mode->switch_bindings = create_list())) goto cleanup; 230 if (!(config->current_mode->switch_bindings = create_list())) goto cleanup;
231 if (!(config->current_mode->gesture_bindings = create_list())) goto cleanup;
225 list_add(config->modes, config->current_mode); 232 list_add(config->modes, config->current_mode);
226 233
227 config->floating_mod = 0; 234 config->floating_mod = 0;
@@ -236,7 +243,7 @@ static void config_defaults(struct sway_config *config) {
236 config->default_layout = L_NONE; 243 config->default_layout = L_NONE;
237 config->default_orientation = L_NONE; 244 config->default_orientation = L_NONE;
238 if (!(config->font = strdup("monospace 10"))) goto cleanup; 245 if (!(config->font = strdup("monospace 10"))) goto cleanup;
239 config->font_height = 17; // height of monospace 10 246 config->font_description = pango_font_description_from_string(config->font);
240 config->urgent_timeout = 500; 247 config->urgent_timeout = 500;
241 config->focus_on_window_activation = FOWA_URGENT; 248 config->focus_on_window_activation = FOWA_URGENT;
242 config->popup_during_fullscreen = POPUP_SMART; 249 config->popup_during_fullscreen = POPUP_SMART;
@@ -266,8 +273,9 @@ static void config_defaults(struct sway_config *config) {
266 config->title_align = ALIGN_LEFT; 273 config->title_align = ALIGN_LEFT;
267 config->tiling_drag = true; 274 config->tiling_drag = true;
268 config->tiling_drag_threshold = 9; 275 config->tiling_drag_threshold = 9;
276 config->primary_selection = true;
269 277
270 config->smart_gaps = false; 278 config->smart_gaps = SMART_GAPS_OFF;
271 config->gaps_inner = 0; 279 config->gaps_inner = 0;
272 config->gaps_outer.top = 0; 280 config->gaps_outer.top = 0;
273 config->gaps_outer.right = 0; 281 config->gaps_outer.right = 0;
@@ -291,6 +299,8 @@ static void config_defaults(struct sway_config *config) {
291 config->hide_edge_borders_smart = ESMART_OFF; 299 config->hide_edge_borders_smart = ESMART_OFF;
292 config->hide_lone_tab = false; 300 config->hide_lone_tab = false;
293 301
302 config->has_focused_tab_title = false;
303
294 // border colors 304 // border colors
295 color_to_rgba(config->border_colors.focused.border, 0x4C7899FF); 305 color_to_rgba(config->border_colors.focused.border, 0x4C7899FF);
296 color_to_rgba(config->border_colors.focused.background, 0x285577FF); 306 color_to_rgba(config->border_colors.focused.background, 0x285577FF);
@@ -338,35 +348,62 @@ static bool file_exists(const char *path) {
338 return path && access(path, R_OK) != -1; 348 return path && access(path, R_OK) != -1;
339} 349}
340 350
351static char *config_path(const char *prefix, const char *config_folder) {
352 if (!prefix || !prefix[0] || !config_folder || !config_folder[0]) {
353 return NULL;
354 }
355
356 const char *filename = "config";
357
358 size_t size = 3 + strlen(prefix) + strlen(config_folder) + strlen(filename);
359 char *path = calloc(size, sizeof(char));
360 snprintf(path, size, "%s/%s/%s", prefix, config_folder, filename);
361 return path;
362}
363
341static char *get_config_path(void) { 364static char *get_config_path(void) {
342 static const char *config_paths[] = { 365 char *path = NULL;
343 "$HOME/.sway/config", 366 const char *home = getenv("HOME");
344 "$XDG_CONFIG_HOME/sway/config", 367 char *config_home_fallback = NULL;
345 "$HOME/.i3/config", 368
346 "$XDG_CONFIG_HOME/i3/config", 369 const char *config_home = getenv("XDG_CONFIG_HOME");
347 SYSCONFDIR "/sway/config", 370 if ((config_home == NULL || config_home[0] == '\0') && home != NULL) {
348 SYSCONFDIR "/i3/config", 371 size_t size_fallback = 1 + strlen(home) + strlen("/.config");
372 config_home_fallback = calloc(size_fallback, sizeof(char));
373 if (config_home_fallback != NULL)
374 snprintf(config_home_fallback, size_fallback, "%s/.config", home);
375 config_home = config_home_fallback;
376 }
377
378 struct config_path {
379 const char *prefix;
380 const char *config_folder;
349 }; 381 };
350 382
351 char *config_home = getenv("XDG_CONFIG_HOME"); 383 struct config_path config_paths[] = {
352 if (!config_home || !*config_home) { 384 { .prefix = home, .config_folder = ".sway"},
353 config_paths[1] = "$HOME/.config/sway/config"; 385 { .prefix = config_home, .config_folder = "sway"},
354 config_paths[3] = "$HOME/.config/i3/config"; 386 { .prefix = home, .config_folder = ".i3"},
355 } 387 { .prefix = config_home, .config_folder = "i3"},
388 { .prefix = SYSCONFDIR, .config_folder = "sway"},
389 { .prefix = SYSCONFDIR, .config_folder = "i3"}
390 };
356 391
357 for (size_t i = 0; i < sizeof(config_paths) / sizeof(char *); ++i) { 392 size_t num_config_paths = sizeof(config_paths)/sizeof(config_paths[0]);
358 wordexp_t p; 393 for (size_t i = 0; i < num_config_paths; i++) {
359 if (wordexp(config_paths[i], &p, WRDE_UNDEF) == 0) { 394 path = config_path(config_paths[i].prefix, config_paths[i].config_folder);
360 char *path = strdup(p.we_wordv[0]); 395 if (!path) {
361 wordfree(&p); 396 continue;
362 if (file_exists(path)) {
363 return path;
364 }
365 free(path);
366 } 397 }
398 if (file_exists(path)) {
399 break;
400 }
401 free(path);
402 path = NULL;
367 } 403 }
368 404
369 return NULL; 405 free(config_home_fallback);
406 return path;
370} 407}
371 408
372static bool load_config(const char *path, struct sway_config *config, 409static bool load_config(const char *path, struct sway_config *config,
@@ -514,6 +551,9 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
514 return success; 551 return success;
515 } 552 }
516 553
554 // Only really necessary if not explicitly `font` is set in the config.
555 config_update_font_height();
556
517 if (is_active && !validating) { 557 if (is_active && !validating) {
518 input_manager_verify_fallback_seat(); 558 input_manager_verify_fallback_seat();
519 559
@@ -884,23 +924,18 @@ void config_add_swaynag_warning(char *fmt, ...) {
884 if (config->reading && !config->validating) { 924 if (config->reading && !config->validating) {
885 va_list args; 925 va_list args;
886 va_start(args, fmt); 926 va_start(args, fmt);
887 size_t length = vsnprintf(NULL, 0, fmt, args) + 1; 927 char *str = vformat_str(fmt, args);
888 va_end(args); 928 va_end(args);
889 929 if (str == NULL) {
890 char *temp = malloc(length + 1);
891 if (!temp) {
892 sway_log(SWAY_ERROR, "Failed to allocate buffer for warning.");
893 return; 930 return;
894 } 931 }
895 932
896 va_start(args, fmt);
897 vsnprintf(temp, length, fmt, args);
898 va_end(args);
899
900 swaynag_log(config->swaynag_command, &config->swaynag_config_errors, 933 swaynag_log(config->swaynag_command, &config->swaynag_config_errors,
901 "Warning on line %i (%s) '%s': %s", 934 "Warning on line %i (%s) '%s': %s",
902 config->current_config_line_number, config->current_config_path, 935 config->current_config_line_number, config->current_config_path,
903 config->current_config_line, temp); 936 config->current_config_line, str);
937
938 free(str);
904 } 939 }
905} 940}
906 941
@@ -940,7 +975,7 @@ char *do_var_replacement(char *str) {
940 int offset = find - str; 975 int offset = find - str;
941 strncpy(newptr, str, offset); 976 strncpy(newptr, str, offset);
942 newptr += offset; 977 newptr += offset;
943 strncpy(newptr, var->value, vvlen); 978 memcpy(newptr, var->value, vvlen);
944 newptr += vvlen; 979 newptr += vvlen;
945 strcpy(newptr, find + vnlen); 980 strcpy(newptr, find + vnlen);
946 free(str); 981 free(str);
@@ -964,31 +999,11 @@ int workspace_output_cmp_workspace(const void *a, const void *b) {
964 return lenient_strcmp(wsa->workspace, wsb->workspace); 999 return lenient_strcmp(wsa->workspace, wsb->workspace);
965} 1000}
966 1001
967static void find_font_height_iterator(struct sway_container *con, void *data) {
968 size_t amount_below_baseline = con->title_height - con->title_baseline;
969 size_t extended_height = config->font_baseline + amount_below_baseline;
970 if (extended_height > config->font_height) {
971 config->font_height = extended_height;
972 }
973}
974
975static void find_baseline_iterator(struct sway_container *con, void *data) {
976 bool *recalculate = data;
977 if (*recalculate) {
978 container_calculate_title_height(con);
979 }
980 if (con->title_baseline > config->font_baseline) {
981 config->font_baseline = con->title_baseline;
982 }
983}
984 1002
985void config_update_font_height(bool recalculate) { 1003void config_update_font_height(void) {
986 size_t prev_max_height = config->font_height; 1004 int prev_max_height = config->font_height;
987 config->font_height = 0;
988 config->font_baseline = 0;
989 1005
990 root_for_each_container(find_baseline_iterator, &recalculate); 1006 get_text_metrics(config->font_description, &config->font_height, &config->font_baseline);
991 root_for_each_container(find_font_height_iterator, NULL);
992 1007
993 if (config->font_height != prev_max_height) { 1008 if (config->font_height != prev_max_height) {
994 arrange_root(); 1009 arrange_root();