diff options
author | Ian Fan <ianfan0@gmail.com> | 2018-10-08 12:05:18 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-08 12:05:18 +0000 |
commit | b3b17280de54021657eabf2df4c3dbfd0039bac8 (patch) | |
tree | d2602caa071680a898a80f8096ed8f787103329e | |
parent | Merge pull request #2786 from swaywm/no-op-client-commands (diff) | |
parent | Don't apply seat config when validating (diff) | |
download | sway-b3b17280de54021657eabf2df4c3dbfd0039bac8.tar.gz sway-b3b17280de54021657eabf2df4c3dbfd0039bac8.tar.zst sway-b3b17280de54021657eabf2df4c3dbfd0039bac8.zip |
Merge pull request #2789 from RyanDwyer/reload-idle
Reload config using idle event
-rw-r--r-- | include/sway/config.h | 1 | ||||
-rw-r--r-- | sway/commands/bind.c | 49 | ||||
-rw-r--r-- | sway/commands/reload.c | 36 | ||||
-rw-r--r-- | sway/commands/seat/attach.c | 4 | ||||
-rw-r--r-- | sway/commands/seat/fallback.c | 4 | ||||
-rw-r--r-- | sway/config.c | 6 | ||||
-rw-r--r-- | sway/input/keyboard.c | 20 |
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 | ||
33 | static 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 | */ |
308 | void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) { | 278 | void 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 | ||
9 | struct cmd_results *cmd_reload(int argc, char **argv) { | 11 | static 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 | |||
46 | struct 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"); |