diff options
Diffstat (limited to 'sway/config.c')
| -rw-r--r-- | sway/config.c | 223 | 
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;  | 
