summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sway/config.h1
-rw-r--r--sway/commands/bind.c49
-rw-r--r--sway/commands/reload.c36
-rw-r--r--sway/commands/seat/attach.c4
-rw-r--r--sway/commands/seat/fallback.c4
-rw-r--r--sway/config.c6
-rw-r--r--sway/input/keyboard.c20
7 files changed, 47 insertions, 73 deletions
diff --git a/include/sway/config.h b/include/sway/config.h
index 02ace979..0e51fbfb 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -35,7 +35,6 @@ enum binding_flags {
35 BINDING_BORDER=4, // mouse only; trigger on container border 35 BINDING_BORDER=4, // mouse only; trigger on container border
36 BINDING_CONTENTS=8, // mouse only; trigger on container contents 36 BINDING_CONTENTS=8, // mouse only; trigger on container contents
37 BINDING_TITLEBAR=16, // mouse only; trigger on container titlebar 37 BINDING_TITLEBAR=16, // mouse only; trigger on container titlebar
38 BINDING_RELOAD=32, // the binding runs the reload command
39}; 38};
40 39
41/** 40/**
diff --git a/sway/commands/bind.c b/sway/commands/bind.c
index 820c2a6a..701d9746 100644
--- a/sway/commands/bind.c
+++ b/sway/commands/bind.c
@@ -30,33 +30,6 @@ void free_sway_binding(struct sway_binding *binding) {
30 free(binding); 30 free(binding);
31} 31}
32 32
33static struct sway_binding *sway_binding_dup(struct sway_binding *sb) {
34 struct sway_binding *new_sb = calloc(1, sizeof(struct sway_binding));
35 if (!new_sb) {
36 return NULL;
37 }
38
39 new_sb->type = sb->type;
40 new_sb->order = sb->order;
41 new_sb->flags = sb->flags;
42 new_sb->modifiers = sb->modifiers;
43 new_sb->command = strdup(sb->command);
44
45 new_sb->keys = create_list();
46 int i;
47 for (i = 0; i < sb->keys->length; ++i) {
48 xkb_keysym_t *key = malloc(sizeof(xkb_keysym_t));
49 if (!key) {
50 free_sway_binding(new_sb);
51 return NULL;
52 }
53 *key = *(xkb_keysym_t *)sb->keys->items[i];
54 list_add(new_sb->keys, key);
55 }
56
57 return new_sb;
58}
59
60/** 33/**
61 * Returns true if the bindings have the same key and modifier combinations. 34 * Returns true if the bindings have the same key and modifier combinations.
62 * Note that keyboard layout is not considered, so the bindings might actually 35 * Note that keyboard layout is not considered, so the bindings might actually
@@ -214,9 +187,6 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv,
214 } 187 }
215 188
216 binding->command = join_args(argv + 1, argc - 1); 189 binding->command = join_args(argv + 1, argc - 1);
217 if (strcasestr(binding->command, "reload")) {
218 binding->flags |= BINDING_RELOAD;
219 }
220 190
221 list_t *split = split_string(argv[0], "+"); 191 list_t *split = split_string(argv[0], "+");
222 for (int i = 0; i < split->length; ++i) { 192 for (int i = 0; i < split->length; ++i) {
@@ -306,31 +276,16 @@ struct cmd_results *cmd_bindcode(int argc, char **argv) {
306 * Execute the command associated to a binding 276 * Execute the command associated to a binding
307 */ 277 */
308void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) { 278void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) {
309 wlr_log(WLR_DEBUG, "running command for binding: %s", 279 wlr_log(WLR_DEBUG, "running command for binding: %s", binding->command);
310 binding->command);
311
312 struct sway_binding *binding_copy = binding;
313 // if this is a reload command we need to make a duplicate of the
314 // binding since it will be gone after the reload has completed.
315 if (binding->flags & BINDING_RELOAD) {
316 binding_copy = sway_binding_dup(binding);
317 if (!binding_copy) {
318 wlr_log(WLR_ERROR, "Failed to duplicate binding during reload");
319 return;
320 }
321 }
322 280
323 config->handler_context.seat = seat; 281 config->handler_context.seat = seat;
324 struct cmd_results *results = execute_command(binding->command, NULL, NULL); 282 struct cmd_results *results = execute_command(binding->command, NULL, NULL);
325 if (results->status == CMD_SUCCESS) { 283 if (results->status == CMD_SUCCESS) {
326 ipc_event_binding(binding_copy); 284 ipc_event_binding(binding);
327 } else { 285 } else {
328 wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)", 286 wlr_log(WLR_DEBUG, "could not run command for binding: %s (%s)",
329 binding->command, results->error); 287 binding->command, results->error);
330 } 288 }
331 289
332 if (binding_copy->flags & BINDING_RELOAD) {
333 free_sway_binding(binding_copy);
334 }
335 free_cmd_results(results); 290 free_cmd_results(results);
336} 291}
diff --git a/sway/commands/reload.c b/sway/commands/reload.c
index 36fb9092..9e136d48 100644
--- a/sway/commands/reload.c
+++ b/sway/commands/reload.c
@@ -3,15 +3,12 @@
3#include "sway/commands.h" 3#include "sway/commands.h"
4#include "sway/config.h" 4#include "sway/config.h"
5#include "sway/ipc-server.h" 5#include "sway/ipc-server.h"
6#include "sway/server.h"
6#include "sway/tree/arrange.h" 7#include "sway/tree/arrange.h"
7#include "list.h" 8#include "list.h"
9#include "log.h"
8 10
9struct cmd_results *cmd_reload(int argc, char **argv) { 11static void do_reload(void *data) {
10 struct cmd_results *error = NULL;
11 if ((error = checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0))) {
12 return error;
13 }
14
15 // store bar ids to check against new bars for barconfig_update events 12 // store bar ids to check against new bars for barconfig_update events
16 list_t *bar_ids = create_list(); 13 list_t *bar_ids = create_list();
17 for (int i = 0; i < config->bars->length; ++i) { 14 for (int i = 0; i < config->bars->length; ++i) {
@@ -20,9 +17,12 @@ struct cmd_results *cmd_reload(int argc, char **argv) {
20 } 17 }
21 18
22 if (!load_main_config(config->current_config_path, true, false)) { 19 if (!load_main_config(config->current_config_path, true, false)) {
23 return cmd_results_new(CMD_FAILURE, "reload", 20 wlr_log(WLR_ERROR, "Error(s) reloading config");
24 "Error(s) reloading config."); 21 list_foreach(bar_ids, free);
22 list_free(bar_ids);
23 return;
25 } 24 }
25
26 ipc_event_workspace(NULL, NULL, "reload"); 26 ipc_event_workspace(NULL, NULL, "reload");
27 27
28 load_swaybars(); 28 load_swaybars();
@@ -37,12 +37,26 @@ struct cmd_results *cmd_reload(int argc, char **argv) {
37 } 37 }
38 } 38 }
39 39
40 for (int i = 0; i < bar_ids->length; ++i) { 40 list_foreach(bar_ids, free);
41 free(bar_ids->items[i]);
42 }
43 list_free(bar_ids); 41 list_free(bar_ids);
44 42
45 arrange_root(); 43 arrange_root();
44}
45
46struct cmd_results *cmd_reload(int argc, char **argv) {
47 struct cmd_results *error = NULL;
48 if ((error = checkarg(argc, "reload", EXPECTED_EQUAL_TO, 0))) {
49 return error;
50 }
51
52 if (!load_main_config(config->current_config_path, true, true)) {
53 return cmd_results_new(CMD_FAILURE, "reload",
54 "Error(s) reloading config.");
55 }
56
57 // The reload command frees a lot of stuff, so to avoid use-after-frees
58 // we schedule the reload to happen using an idle event.
59 wl_event_loop_add_idle(server.wl_event_loop, do_reload, NULL);
46 60
47 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 61 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
48} 62}
diff --git a/sway/commands/seat/attach.c b/sway/commands/seat/attach.c
index 3e771c00..6b4bcf1f 100644
--- a/sway/commands/seat/attach.c
+++ b/sway/commands/seat/attach.c
@@ -23,6 +23,8 @@ struct cmd_results *seat_cmd_attach(int argc, char **argv) {
23 new_attachment->identifier = strdup(argv[0]); 23 new_attachment->identifier = strdup(argv[0]);
24 list_add(new_config->attachments, new_attachment); 24 list_add(new_config->attachments, new_attachment);
25 25
26 apply_seat_config(new_config); 26 if (!config->validating) {
27 apply_seat_config(new_config);
28 }
27 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 29 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
28} 30}
diff --git a/sway/commands/seat/fallback.c b/sway/commands/seat/fallback.c
index 56feaab5..11f5a08c 100644
--- a/sway/commands/seat/fallback.c
+++ b/sway/commands/seat/fallback.c
@@ -27,6 +27,8 @@ struct cmd_results *seat_cmd_fallback(int argc, char **argv) {
27 "Expected 'fallback <true|false>'"); 27 "Expected 'fallback <true|false>'");
28 } 28 }
29 29
30 apply_seat_config(new_config); 30 if (!config->validating) {
31 apply_seat_config(new_config);
32 }
31 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 33 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
32} 34}
diff --git a/sway/config.c b/sway/config.c
index b56c4f71..8f8ed438 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -457,6 +457,12 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
457 success = success && load_config(path, config, 457 success = success && load_config(path, config,
458 &config->swaynag_config_errors); 458 &config->swaynag_config_errors);
459 459
460 if (validating) {
461 free_config(config);
462 config = old_config;
463 return success;
464 }
465
460 if (is_active) { 466 if (is_active) {
461 for (int i = 0; i < config->output_configs->length; i++) { 467 for (int i = 0; i < config->output_configs->length; i++) {
462 apply_output_config_to_outputs(config->output_configs->items[i]); 468 apply_output_config_to_outputs(config->output_configs->items[i]);
diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c
index 5fc8a806..fb1fe7b5 100644
--- a/sway/input/keyboard.c
+++ b/sway/input/keyboard.c
@@ -264,31 +264,27 @@ static void handle_keyboard_key(struct wl_listener *listener, void *data) {
264 } 264 }
265 265
266 // Identify and execute active pressed binding 266 // Identify and execute active pressed binding
267 struct sway_binding *next_repeat_binding = NULL; 267 struct sway_binding *binding = NULL;
268 if (event->state == WLR_KEY_PRESSED) { 268 if (event->state == WLR_KEY_PRESSED) {
269 struct sway_binding *binding_pressed = NULL;
270 get_active_binding(&keyboard->state_keycodes, 269 get_active_binding(&keyboard->state_keycodes,
271 config->current_mode->keycode_bindings, &binding_pressed, 270 config->current_mode->keycode_bindings, &binding,
272 code_modifiers, false, input_inhibited); 271 code_modifiers, false, input_inhibited);
273 get_active_binding(&keyboard->state_keysyms_translated, 272 get_active_binding(&keyboard->state_keysyms_translated,
274 config->current_mode->keysym_bindings, &binding_pressed, 273 config->current_mode->keysym_bindings, &binding,
275 translated_modifiers, false, input_inhibited); 274 translated_modifiers, false, input_inhibited);
276 get_active_binding(&keyboard->state_keysyms_raw, 275 get_active_binding(&keyboard->state_keysyms_raw,
277 config->current_mode->keysym_bindings, &binding_pressed, 276 config->current_mode->keysym_bindings, &binding,
278 raw_modifiers, false, input_inhibited); 277 raw_modifiers, false, input_inhibited);
279 278
280 if (binding_pressed) { 279 if (binding) {
281 if ((binding_pressed->flags & BINDING_RELOAD) == 0) { 280 seat_execute_command(seat, binding);
282 next_repeat_binding = binding_pressed;
283 }
284 seat_execute_command(seat, binding_pressed);
285 handled = true; 281 handled = true;
286 } 282 }
287 } 283 }
288 284
289 // Set up (or clear) keyboard repeat for a pressed binding 285 // Set up (or clear) keyboard repeat for a pressed binding
290 if (next_repeat_binding && wlr_device->keyboard->repeat_info.delay > 0) { 286 if (binding && wlr_device->keyboard->repeat_info.delay > 0) {
291 keyboard->repeat_binding = next_repeat_binding; 287 keyboard->repeat_binding = binding;
292 if (wl_event_source_timer_update(keyboard->key_repeat_source, 288 if (wl_event_source_timer_update(keyboard->key_repeat_source,
293 wlr_device->keyboard->repeat_info.delay) < 0) { 289 wlr_device->keyboard->repeat_info.delay) < 0) {
294 wlr_log(WLR_DEBUG, "failed to set key repeat timer"); 290 wlr_log(WLR_DEBUG, "failed to set key repeat timer");