aboutsummaryrefslogtreecommitdiff
path: root/sway/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/config.c')
-rw-r--r--sway/config.c223
1 files changed, 130 insertions, 93 deletions
diff --git a/sway/config.c b/sway/config.c
index 6f65d0c2..18fee404 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -1,5 +1,4 @@
-#define _POSIX_C_SOURCE 200809L
-#define _XOPEN_SOURCE 700
+#define _XOPEN_SOURCE 700 // for realpath
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -14,11 +13,7 @@
#include <limits.h>
#include <dirent.h>
#include <strings.h>
-#ifdef __linux__
#include <linux/input-event-codes.h>
-#elif __FreeBSD__
-#include <dev/evdev/input-event-codes.h>
-#endif
#include <wlr/types/wlr_output.h>
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
@@ -31,7 +26,6 @@
#include "sway/tree/workspace.h"
#include "cairo.h"
#include "pango.h"
-#include "readline.h"
#include "stringop.h"
#include "list.h"
#include "log.h"
@@ -39,26 +33,24 @@
struct sway_config *config = NULL;
static void free_mode(struct sway_mode *mode) {
- int i;
-
if (!mode) {
return;
}
free(mode->name);
if (mode->keysym_bindings) {
- for (i = 0; i < mode->keysym_bindings->length; i++) {
+ for (int i = 0; i < mode->keysym_bindings->length; i++) {
free_sway_binding(mode->keysym_bindings->items[i]);
}
list_free(mode->keysym_bindings);
}
if (mode->keycode_bindings) {
- for (i = 0; i < mode->keycode_bindings->length; i++) {
+ for (int i = 0; i < mode->keycode_bindings->length; i++) {
free_sway_binding(mode->keycode_bindings->items[i]);
}
list_free(mode->keycode_bindings);
}
if (mode->mouse_bindings) {
- for (i = 0; i < mode->mouse_bindings->length; i++) {
+ for (int i = 0; i < mode->mouse_bindings->length; i++) {
free_sway_binding(mode->mouse_bindings->items[i]);
}
list_free(mode->mouse_bindings);
@@ -214,6 +206,10 @@ static void config_defaults(struct sway_config *config) {
config->popup_during_fullscreen = POPUP_SMART;
config->xwayland = true;
+ config->titlebar_border_thickness = 1;
+ config->titlebar_h_padding = 5;
+ config->titlebar_v_padding = 4;
+
// floating view
config->floating_maximum_width = 0;
config->floating_maximum_height = 0;
@@ -231,7 +227,9 @@ static void config_defaults(struct sway_config *config) {
config->auto_back_and_forth = false;
config->reading = false;
config->show_marks = true;
+ config->title_align = ALIGN_LEFT;
config->tiling_drag = true;
+ config->tiling_drag_threshold = 9;
config->smart_gaps = false;
config->gaps_inner = 0;
@@ -313,27 +311,16 @@ static char *get_config_path(void) {
SYSCONFDIR "/i3/config",
};
- if (!getenv("XDG_CONFIG_HOME")) {
- char *home = getenv("HOME");
- char *config_home = malloc(strlen(home) + strlen("/.config") + 1);
- if (!config_home) {
- wlr_log(WLR_ERROR, "Unable to allocate $HOME/.config");
- } else {
- strcpy(config_home, home);
- strcat(config_home, "/.config");
- setenv("XDG_CONFIG_HOME", config_home, 1);
- wlr_log(WLR_DEBUG, "Set XDG_CONFIG_HOME to %s", config_home);
- free(config_home);
- }
+ char *config_home = getenv("XDG_CONFIG_HOME");
+ if (!config_home || !*config_home) {
+ config_paths[1] = "$HOME/.config/sway/config";
+ config_paths[3] = "$HOME/.config/i3/config";
}
- wordexp_t p;
- char *path;
-
- int i;
- for (i = 0; i < (int)(sizeof(config_paths) / sizeof(char *)); ++i) {
- if (wordexp(config_paths[i], &p, 0) == 0) {
- path = strdup(p.we_wordv[0]);
+ for (size_t i = 0; i < sizeof(config_paths) / sizeof(char *); ++i) {
+ wordexp_t p;
+ if (wordexp(config_paths[i], &p, WRDE_UNDEF) == 0) {
+ char *path = strdup(p.we_wordv[0]);
wordfree(&p);
if (file_exists(path)) {
return path;
@@ -342,7 +329,7 @@ static char *get_config_path(void) {
}
}
- return NULL; // Not reached
+ return NULL;
}
static bool load_config(const char *path, struct sway_config *config,
@@ -402,7 +389,7 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
&old_config->swaynag_config_errors,
sizeof(struct swaynag_instance));
- create_default_output_configs();
+ input_manager_reset_all_inputs();
}
config->current_config_path = path;
@@ -454,7 +441,7 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
}
}
- free_flat_list(secconfigs);
+ list_free_items_and_destroy(secconfigs);
}
*/
@@ -475,6 +462,11 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
if (config->swaynag_config_errors.pid > 0) {
swaynag_show(&config->swaynag_config_errors);
}
+
+ input_manager_verify_fallback_seat();
+ for (int i = 0; i < config->seat_configs->length; i++) {
+ input_manager_apply_seat_config(config->seat_configs->items[i]);
+ }
}
if (old_config) {
@@ -581,29 +573,56 @@ bool load_include_configs(const char *path, struct sway_config *config,
return true;
}
-static int detect_brace_on_following_line(FILE *file, char *line,
- int line_number) {
- int lines = 0;
- if (line[strlen(line) - 1] != '{' && line[strlen(line) - 1] != '}') {
- char *peeked = NULL;
- long position = 0;
- do {
- free(peeked);
- peeked = peek_line(file, lines, &position);
- if (peeked) {
- peeked = strip_whitespace(peeked);
+// get line, with backslash continuation
+static ssize_t getline_with_cont(char **lineptr, size_t *line_size, FILE *file,
+ int *nlines) {
+ char *next_line = NULL;
+ size_t next_line_size = 0;
+ ssize_t nread = getline(lineptr, line_size, file);
+ *nlines = nread == -1 ? 0 : 1;
+ while (nread >= 2 && strcmp(&(*lineptr)[nread - 2], "\\\n") == 0) {
+ ssize_t next_nread = getline(&next_line, &next_line_size, file);
+ if (next_nread == -1) {
+ break;
+ }
+ (*nlines)++;
+
+ nread += next_nread - 2;
+ if ((ssize_t) *line_size < nread + 1) {
+ *line_size = nread + 1;
+ *lineptr = realloc(*lineptr, *line_size);
+ if (!*lineptr) {
+ nread = -1;
+ break;
}
- lines++;
- } while (peeked && strlen(peeked) == 0);
+ }
+ strcpy(&(*lineptr)[nread - next_nread], next_line);
+ }
+ free(next_line);
+ return nread;
+}
- if (peeked && strlen(peeked) == 1 && peeked[0] == '{') {
- fseek(file, position, SEEK_SET);
- } else {
- lines = 0;
+static int detect_brace(FILE *file) {
+ int ret = 0;
+ int lines = 0;
+ long pos = ftell(file);
+ char *line = NULL;
+ size_t line_size = 0;
+ while ((getline(&line, &line_size, file)) != -1) {
+ lines++;
+ strip_whitespace(line);
+ if (*line) {
+ if (strcmp(line, "{") == 0) {
+ ret = lines;
+ }
+ break;
}
- free(peeked);
}
- return lines;
+ free(line);
+ if (ret == 0) {
+ fseek(file, pos, SEEK_SET);
+ }
+ return ret;
}
static char *expand_line(const char *block, const char *line, bool add_brace) {
@@ -645,58 +664,51 @@ bool read_config(FILE *file, struct sway_config *config,
bool success = true;
int line_number = 0;
- char *line;
+ char *line = NULL;
+ size_t line_size = 0;
+ ssize_t nread;
list_t *stack = create_list();
size_t read = 0;
- while (!feof(file)) {
- char *block = stack->length ? stack->items[0] : NULL;
- line = read_line(file);
- if (!line) {
- continue;
- }
- line_number++;
- wlr_log(WLR_DEBUG, "Read line %d: %s", line_number, line);
-
+ int nlines = 0;
+ while ((nread = getline_with_cont(&line, &line_size, file, &nlines)) != -1) {
if (reading_main_config) {
- size_t length = strlen(line);
-
- if (read + length > config_size) {
+ if (read + nread > config_size) {
wlr_log(WLR_ERROR, "Config file changed during reading");
- list_foreach(stack, free);
- list_free(stack);
- free(line);
- return false;
+ success = false;
+ break;
}
- strcpy(this_config + read, line);
- if (line_number != 1) {
- this_config[read - 1] = '\n';
- }
- read += length + 1;
+ strcpy(&this_config[read], line);
+ read += nread;
}
- line = strip_whitespace(line);
- if (line[0] == '#') {
- free(line);
- continue;
+ if (line[nread - 1] == '\n') {
+ line[nread - 1] = '\0';
}
- if (strlen(line) == 0) {
- free(line);
+
+ line_number += nlines;
+ wlr_log(WLR_DEBUG, "Read line %d: %s", line_number, line);
+
+ strip_whitespace(line);
+ if (!*line || line[0] == '#') {
continue;
}
- int brace_detected = detect_brace_on_following_line(file, line,
- line_number);
- if (brace_detected > 0) {
- line_number += brace_detected;
- wlr_log(WLR_DEBUG, "Detected open brace on line %d", line_number);
+ int brace_detected = 0;
+ if (line[strlen(line) - 1] != '{' && line[strlen(line) - 1] != '}') {
+ brace_detected = detect_brace(file);
+ if (brace_detected > 0) {
+ line_number += brace_detected;
+ wlr_log(WLR_DEBUG, "Detected open brace on line %d", line_number);
+ }
}
+ char *block = stack->length ? stack->items[0] : NULL;
char *expanded = expand_line(block, line, brace_detected > 0);
if (!expanded) {
- list_foreach(stack, free);
- list_free(stack);
- free(line);
- return false;
+ success = false;
+ break;
}
+ config->current_config_line_number = line_number;
+ config->current_config_line = line;
struct cmd_results *res;
if (block && strcmp(block, "<commands>") == 0) {
// Special case
@@ -753,15 +765,40 @@ bool read_config(FILE *file, struct sway_config *config,
default:;
}
free(expanded);
- free(line);
free_cmd_results(res);
}
- list_foreach(stack, free);
- list_free(stack);
+ free(line);
+ list_free_items_and_destroy(stack);
+ config->current_config_line_number = 0;
+ config->current_config_line = NULL;
return success;
}
+void config_add_swaynag_warning(char *fmt, ...) {
+ if (config->reading && !config->validating) {
+ va_list args;
+ va_start(args, fmt);
+ size_t length = vsnprintf(NULL, 0, fmt, args) + 1;
+ va_end(args);
+
+ char *temp = malloc(length + 1);
+ if (!temp) {
+ wlr_log(WLR_ERROR, "Failed to allocate buffer for warning.");
+ return;
+ }
+
+ va_start(args, fmt);
+ vsnprintf(temp, length, fmt, args);
+ va_end(args);
+
+ swaynag_log(config->swaynag_command, &config->swaynag_config_errors,
+ "Warning on line %i (%s) '%s': %s",
+ config->current_config_line_number, config->current_config_path,
+ config->current_config_line, temp);
+ }
+}
+
char *do_var_replacement(char *str) {
int i;
char *find = str;