diff options
Diffstat (limited to 'sway/config.c')
-rw-r--r-- | sway/config.c | 218 |
1 files changed, 113 insertions, 105 deletions
diff --git a/sway/config.c b/sway/config.c index f1de6080..9f65e8a2 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include "log.h" | 8 | #include "log.h" |
9 | #include "commands.h" | 9 | #include "commands.h" |
10 | #include "config.h" | 10 | #include "config.h" |
11 | #include "layout.h" | ||
11 | 12 | ||
12 | struct sway_config *config; | 13 | struct sway_config *config; |
13 | 14 | ||
@@ -15,121 +16,143 @@ static bool exists(const char *path) { | |||
15 | return access(path, R_OK) != -1; | 16 | return access(path, R_OK) != -1; |
16 | } | 17 | } |
17 | 18 | ||
18 | static char *get_config_path() { | 19 | void config_defaults(struct sway_config *config) { |
19 | char *name = "/.sway/config"; | 20 | config->symbols = create_list(); |
20 | const char *home = getenv("HOME"); | 21 | config->modes = create_list(); |
22 | config->cmd_queue = create_list(); | ||
23 | config->workspace_outputs = create_list(); | ||
24 | config->current_mode = malloc(sizeof(struct sway_mode)); | ||
25 | config->current_mode->name = NULL; | ||
26 | config->current_mode->bindings = create_list(); | ||
27 | list_add(config->modes, config->current_mode); | ||
28 | // Flags | ||
29 | config->focus_follows_mouse = true; | ||
30 | config->mouse_warping = true; | ||
31 | config->reloading = false; | ||
32 | config->active = false; | ||
33 | config->failed = false; | ||
34 | config->gaps_inner = 0; | ||
35 | config->gaps_outer = 0; | ||
36 | } | ||
21 | 37 | ||
22 | // Check home dir | 38 | void free_mode(struct sway_mode *mode) { |
23 | sway_log(L_DEBUG, "Trying to find config in ~/.sway/config"); | 39 | free(mode->name); |
24 | char *temp = malloc(strlen(home) + strlen(name) + 1); | 40 | free_flat_list(mode->bindings); |
25 | strcpy(temp, home); | 41 | } |
26 | strcat(temp, name); | ||
27 | if (exists(temp)) { | ||
28 | return temp; | ||
29 | } | ||
30 | 42 | ||
31 | // Check XDG_CONFIG_HOME with fallback to ~/.config/ | 43 | void free_config(struct sway_config *config) { |
32 | sway_log(L_DEBUG, "Trying to find config in XDG_CONFIG_HOME/sway/config"); | 44 | int i; |
33 | char *xdg_config_home = getenv("XDG_CONFIG_HOME"); | 45 | for (i = 0; i < config->modes->length; ++i) { |
34 | if (xdg_config_home == NULL) { | 46 | free_mode((struct sway_mode *)config->modes->items[i]); |
35 | sway_log(L_DEBUG, "Falling back to ~/.config/sway/config"); | ||
36 | name = "/.config/sway/config"; | ||
37 | temp = malloc(strlen(home) + strlen(name) + 1); | ||
38 | strcpy(temp, home); | ||
39 | strcat(temp, name); | ||
40 | } else { | ||
41 | name = "/sway/config"; | ||
42 | temp = malloc(strlen(xdg_config_home) + strlen(name) + 1); | ||
43 | strcpy(xdg_config_home, home); | ||
44 | strcat(temp, name); | ||
45 | } | 47 | } |
46 | if (exists(temp)) { | 48 | free_flat_list(config->modes); |
47 | return temp; | 49 | for (i = 0; i < config->workspace_outputs->length; ++i) { |
50 | struct workspace_output *wso = config->workspace_outputs->items[i]; | ||
51 | free(wso->output); | ||
52 | free(wso->workspace); | ||
48 | } | 53 | } |
49 | 54 | free_flat_list(config->workspace_outputs); | |
50 | // Check /etc/ | 55 | free_flat_list(config->cmd_queue); |
51 | sway_log(L_DEBUG, "Trying to find config in /etc/sway/config"); | 56 | for (i = 0; i < config->symbols->length; ++i) { |
52 | strcpy(temp, "/etc/sway/config"); | 57 | struct sway_variable *sym = config->symbols->items[i]; |
53 | if (exists(temp)) { | 58 | free(sym->name); |
54 | return temp; | 59 | free(sym->value); |
55 | } | 60 | } |
61 | free_flat_list(config->symbols); | ||
62 | } | ||
56 | 63 | ||
57 | // Check XDG_CONFIG_DIRS | 64 | static const char *search_paths[] = { |
58 | sway_log(L_DEBUG, "Trying to find config in XDG_CONFIG_DIRS"); | 65 | "$home/.sway/config", |
59 | char *xdg_config_dirs = getenv("XDG_CONFIG_DIRS"); | 66 | "$config/sway/config", |
60 | if (xdg_config_dirs != NULL) { | 67 | "/etc/sway/config", |
61 | list_t *paths = split_string(xdg_config_dirs, ":"); | 68 | "$home/.i3/config", |
62 | name = "/sway/config"; | 69 | "$config/.i3/config", |
63 | int i; | 70 | "/etc/i3/config" |
64 | for (i = 0; i < paths->length; i++ ) { | 71 | }; |
65 | temp = malloc(strlen(paths->items[i]) + strlen(name) + 1); | ||
66 | strcpy(temp, paths->items[i]); | ||
67 | strcat(temp, name); | ||
68 | if (exists(temp)) { | ||
69 | free_flat_list(paths); | ||
70 | return temp; | ||
71 | } | ||
72 | } | ||
73 | free_flat_list(paths); | ||
74 | } | ||
75 | 72 | ||
76 | //Now fall back to i3 paths and try the same thing | 73 | static char *get_config_path() { |
77 | name = "/.i3/config"; | 74 | char *home = getenv("HOME"); |
78 | sway_log(L_DEBUG, "Trying to find config in ~/.i3/config"); | 75 | if (home) { |
79 | temp = malloc(strlen(home) + strlen(name) + 1); | 76 | home = strdup(getenv("HOME")); |
80 | strcpy(temp, home); | ||
81 | strcat(temp, name); | ||
82 | if (exists(temp)) { | ||
83 | return temp; | ||
84 | } | 77 | } |
85 | 78 | char *config = getenv("XDG_CONFIG_HOME"); | |
86 | sway_log(L_DEBUG, "Trying to find config in XDG_CONFIG_HOME/i3/config"); | 79 | if (config) { |
87 | if (xdg_config_home == NULL) { | 80 | config = strdup(getenv("XDG_CONFIG_HOME")); |
88 | sway_log(L_DEBUG, "Falling back to ~/.config/i3/config"); | 81 | } else if (home) { |
89 | name = "/.config/i3/config"; | 82 | const char *def = "/.config"; |
90 | temp = malloc(strlen(home) + strlen(name) + 1); | 83 | config = malloc(strlen(home) + strlen(def) + 1); |
91 | strcpy(temp, home); | 84 | strcpy(config, home); |
92 | strcat(temp, name); | 85 | strcat(config, def); |
93 | } else { | 86 | } else { |
94 | name = "/i3/config"; | 87 | home = strdup(""); |
95 | temp = malloc(strlen(xdg_config_home) + strlen(name) + 1); | 88 | config = strdup(""); |
96 | strcpy(xdg_config_home, home); | ||
97 | strcat(temp, name); | ||
98 | } | ||
99 | if (exists(temp)) { | ||
100 | return temp; | ||
101 | } | 89 | } |
102 | 90 | ||
103 | sway_log(L_DEBUG, "Trying to find config in /etc/i3/config"); | 91 | // Set up a temporary config for holding set variables |
104 | strcpy(temp, "/etc/i3/config"); | 92 | struct sway_config *temp_config = malloc(sizeof(struct sway_config)); |
105 | if (exists(temp)) { | 93 | config_defaults(temp_config); |
106 | return temp; | 94 | const char *set_home = "set $home "; |
95 | char *_home = malloc(strlen(home) + strlen(set_home) + 1); | ||
96 | strcpy(_home, set_home); | ||
97 | strcat(_home, home); | ||
98 | handle_command(temp_config, _home); | ||
99 | free(_home); | ||
100 | const char *set_config = "set $config "; | ||
101 | char *_config = malloc(strlen(config) + strlen(set_config) + 1); | ||
102 | strcpy(_config, set_config); | ||
103 | strcat(_config, config); | ||
104 | handle_command(temp_config, _config); | ||
105 | free(_config); | ||
106 | |||
107 | char *test = NULL; | ||
108 | int i; | ||
109 | for (i = 0; i < sizeof(search_paths) / sizeof(char *); ++i) { | ||
110 | test = strdup(search_paths[i]); | ||
111 | test = do_var_replacement(temp_config, test); | ||
112 | sway_log(L_DEBUG, "Checking for config at %s", test); | ||
113 | if (exists(test)) { | ||
114 | goto _continue; | ||
115 | } | ||
116 | free(test); | ||
117 | test = NULL; | ||
107 | } | 118 | } |
108 | 119 | ||
109 | sway_log(L_DEBUG, "Trying to find config in XDG_CONFIG_DIRS"); | 120 | sway_log(L_DEBUG, "Trying to find config in XDG_CONFIG_DIRS"); |
121 | char *xdg_config_dirs = getenv("XDG_CONFIG_DIRS"); | ||
110 | if (xdg_config_dirs != NULL) { | 122 | if (xdg_config_dirs != NULL) { |
111 | list_t *paths = split_string(xdg_config_dirs, ":"); | 123 | list_t *paths = split_string(xdg_config_dirs, ":"); |
112 | name = "/i3/config"; | 124 | char *name = "/sway/config"; |
113 | int i; | 125 | int i; |
114 | for (i = 0; i < paths->length; i++ ) { | 126 | for (i = 0; i < paths->length; i++ ) { |
115 | temp = malloc(strlen(paths->items[i]) + strlen(name) + 1); | 127 | test = malloc(strlen(paths->items[i]) + strlen(name) + 1); |
116 | strcpy(temp, paths->items[i]); | 128 | strcpy(test, paths->items[i]); |
117 | strcat(temp, name); | 129 | strcat(test, name); |
118 | if (exists(temp)) { | 130 | if (exists(test)) { |
119 | free_flat_list(paths); | 131 | free_flat_list(paths); |
120 | return temp; | 132 | return test; |
121 | } | 133 | } |
134 | free(test); | ||
135 | test = NULL; | ||
122 | } | 136 | } |
123 | free_flat_list(paths); | 137 | free_flat_list(paths); |
124 | } | 138 | } |
125 | 139 | ||
126 | return NULL; | 140 | _continue: |
141 | free_config(temp_config); | ||
142 | free(home); | ||
143 | free(config); | ||
144 | return test; | ||
127 | } | 145 | } |
128 | 146 | ||
129 | bool load_config(void) { | 147 | bool load_config(const char *file) { |
130 | sway_log(L_INFO, "Loading config"); | 148 | sway_log(L_INFO, "Loading config"); |
131 | 149 | ||
132 | char *path = get_config_path(); | 150 | char *path; |
151 | if (file != NULL) { | ||
152 | path = strdup(file); | ||
153 | } else { | ||
154 | path = get_config_path(); | ||
155 | } | ||
133 | 156 | ||
134 | if (path == NULL) { | 157 | if (path == NULL) { |
135 | sway_log(L_ERROR, "Unable to find a config file!"); | 158 | sway_log(L_ERROR, "Unable to find a config file!"); |
@@ -155,23 +178,6 @@ bool load_config(void) { | |||
155 | return config_load_success; | 178 | return config_load_success; |
156 | } | 179 | } |
157 | 180 | ||
158 | void config_defaults(struct sway_config *config) { | ||
159 | config->symbols = create_list(); | ||
160 | config->modes = create_list(); | ||
161 | config->cmd_queue = create_list(); | ||
162 | config->workspace_outputs = create_list(); | ||
163 | config->current_mode = malloc(sizeof(struct sway_mode)); | ||
164 | config->current_mode->name = NULL; | ||
165 | config->current_mode->bindings = create_list(); | ||
166 | list_add(config->modes, config->current_mode); | ||
167 | // Flags | ||
168 | config->focus_follows_mouse = true; | ||
169 | config->mouse_warping = true; | ||
170 | config->reloading = false; | ||
171 | config->active = false; | ||
172 | config->failed = false; | ||
173 | } | ||
174 | |||
175 | bool read_config(FILE *file, bool is_active) { | 181 | bool read_config(FILE *file, bool is_active) { |
176 | struct sway_config *temp_config = malloc(sizeof(struct sway_config)); | 182 | struct sway_config *temp_config = malloc(sizeof(struct sway_config)); |
177 | config_defaults(temp_config); | 183 | config_defaults(temp_config); |
@@ -188,8 +194,8 @@ bool read_config(FILE *file, bool is_active) { | |||
188 | while (!feof(file)) { | 194 | while (!feof(file)) { |
189 | int _; | 195 | int _; |
190 | char *line = read_line(file); | 196 | char *line = read_line(file); |
191 | line = strip_comments(line); | ||
192 | line = strip_whitespace(line, &_); | 197 | line = strip_whitespace(line, &_); |
198 | line = strip_comments(line); | ||
193 | if (!line[0]) { | 199 | if (!line[0]) { |
194 | goto _continue; | 200 | goto _continue; |
195 | } | 201 | } |
@@ -225,6 +231,8 @@ _continue: | |||
225 | 231 | ||
226 | if (is_active) { | 232 | if (is_active) { |
227 | temp_config->reloading = false; | 233 | temp_config->reloading = false; |
234 | container_map(&root_container, reset_gaps, NULL); | ||
235 | arrange_windows(&root_container, -1, -1); | ||
228 | } | 236 | } |
229 | config = temp_config; | 237 | config = temp_config; |
230 | 238 | ||