aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2019-06-11 21:41:02 -0400
committerLibravatar Simon Ser <contact@emersion.fr>2019-06-12 07:56:41 +0300
commit9670ccee683ab985e89eb04302fb998c4161f2d6 (patch)
treef7cafeaf55a7c139e97a920b0b43bcb080d3a27c
parentFix segfaults caused by faulty command parsing (diff)
downloadsway-9670ccee683ab985e89eb04302fb998c4161f2d6.tar.gz
sway-9670ccee683ab985e89eb04302fb998c4161f2d6.tar.zst
sway-9670ccee683ab985e89eb04302fb998c4161f2d6.zip
bindings: defer while initiailizing
This adds the logic to defer binding execution while sway is still initializing. Without this, the binding command would be executed, but the command handler would return CMD_DEFER, which was being treated as a failure to run. To avoid partial executions, this will defer all bindings while config->active is false.
-rw-r--r--include/sway/config.h5
-rw-r--r--include/sway/input/seat.h2
-rw-r--r--sway/commands/bind.c14
-rw-r--r--sway/config.c18
-rw-r--r--sway/input/seat.c7
-rw-r--r--sway/main.c3
6 files changed, 47 insertions, 2 deletions
diff --git a/include/sway/config.h b/include/sway/config.h
index 57ae3c63..9736a665 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -559,6 +559,11 @@ bool read_config(FILE *file, struct sway_config *config,
559void run_deferred_commands(void); 559void run_deferred_commands(void);
560 560
561/** 561/**
562 * Run the binding commands that were deferred when initializing the inputs
563 */
564void run_deferred_bindings(void);
565
566/**
562 * Adds a warning entry to the swaynag instance used for errors. 567 * Adds a warning entry to the swaynag instance used for errors.
563 */ 568 */
564void config_add_swaynag_warning(char *fmt, ...); 569void config_add_swaynag_warning(char *fmt, ...);
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index eb6c09a1..c963de9b 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -78,6 +78,8 @@ struct sway_seat {
78 78
79 uint32_t last_button_serial; 79 uint32_t last_button_serial;
80 80
81 list_t *deferred_bindings; // struct sway_binding
82
81 struct wl_listener focus_destroy; 83 struct wl_listener focus_destroy;
82 struct wl_listener new_node; 84 struct wl_listener new_node;
83 struct wl_listener request_start_drag; 85 struct wl_listener request_start_drag;
diff --git a/sway/commands/bind.c b/sway/commands/bind.c
index d43c87fb..49b511ad 100644
--- a/sway/commands/bind.c
+++ b/sway/commands/bind.c
@@ -559,8 +559,20 @@ struct cmd_results *cmd_unbindswitch(int argc, char **argv) {
559 * Execute the command associated to a binding 559 * Execute the command associated to a binding
560 */ 560 */
561void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) { 561void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) {
562 sway_log(SWAY_DEBUG, "running command for binding: %s", binding->command); 562 if (!config->active) {
563 sway_log(SWAY_DEBUG, "deferring command for binding: %s",
564 binding->command);
565 struct sway_binding *deferred = calloc(1, sizeof(struct sway_binding));
566 if (!deferred) {
567 sway_log(SWAY_ERROR, "Failed to allocate deferred binding");
568 return;
569 }
570 memcpy(deferred, binding, sizeof(struct sway_binding));
571 list_add(seat->deferred_bindings, deferred);
572 return;
573 }
563 574
575 sway_log(SWAY_DEBUG, "running command for binding: %s", binding->command);
564 struct sway_container *con = NULL; 576 struct sway_container *con = NULL;
565 if (binding->type == BINDING_MOUSESYM 577 if (binding->type == BINDING_MOUSESYM
566 || binding->type == BINDING_MOUSECODE) { 578 || binding->type == BINDING_MOUSECODE) {
diff --git a/sway/config.c b/sway/config.c
index 4f92b403..4e64bd3a 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -644,7 +644,23 @@ void run_deferred_commands(void) {
644 list_free(res_list); 644 list_free(res_list);
645 free(line); 645 free(line);
646 } 646 }
647 transaction_commit_dirty(); 647}
648
649void run_deferred_bindings(void) {
650 struct sway_seat *seat;
651 wl_list_for_each(seat, &(server.input->seats), link) {
652 if (!seat->deferred_bindings->length) {
653 continue;
654 }
655 sway_log(SWAY_DEBUG, "Running deferred bindings for seat %s",
656 seat->wlr_seat->name);
657 while (seat->deferred_bindings->length) {
658 struct sway_binding *binding = seat->deferred_bindings->items[0];
659 seat_execute_command(seat, binding);
660 list_del(seat->deferred_bindings, 0);
661 free_sway_binding(binding);
662 }
663 }
648} 664}
649 665
650// get line, with backslash continuation 666// get line, with backslash continuation
diff --git a/sway/input/seat.c b/sway/input/seat.c
index e6b53736..12309c1d 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -9,6 +9,7 @@
9#include <wlr/types/wlr_primary_selection.h> 9#include <wlr/types/wlr_primary_selection.h>
10#include <wlr/types/wlr_xcursor_manager.h> 10#include <wlr/types/wlr_xcursor_manager.h>
11#include "config.h" 11#include "config.h"
12#include "list.h"
12#include "log.h" 13#include "log.h"
13#include "sway/desktop.h" 14#include "sway/desktop.h"
14#include "sway/input/cursor.h" 15#include "sway/input/cursor.h"
@@ -51,6 +52,10 @@ void seat_destroy(struct sway_seat *seat) {
51 wl_list_remove(&seat->request_set_primary_selection.link); 52 wl_list_remove(&seat->request_set_primary_selection.link);
52 wl_list_remove(&seat->link); 53 wl_list_remove(&seat->link);
53 wlr_seat_destroy(seat->wlr_seat); 54 wlr_seat_destroy(seat->wlr_seat);
55 for (int i = 0; i < seat->deferred_bindings->length; i++) {
56 free_sway_binding(seat->deferred_bindings->items[i]);
57 }
58 list_free(seat->deferred_bindings);
54 free(seat->prev_workspace_name); 59 free(seat->prev_workspace_name);
55 free(seat); 60 free(seat);
56} 61}
@@ -445,6 +450,8 @@ struct sway_seat *seat_create(const char *seat_name) {
445 root_for_each_workspace(collect_focus_workspace_iter, seat); 450 root_for_each_workspace(collect_focus_workspace_iter, seat);
446 root_for_each_container(collect_focus_container_iter, seat); 451 root_for_each_container(collect_focus_container_iter, seat);
447 452
453 seat->deferred_bindings = create_list();
454
448 if (!wl_list_empty(&server.input->seats)) { 455 if (!wl_list_empty(&server.input->seats)) {
449 // Since this is not the first seat, attempt to set initial focus 456 // Since this is not the first seat, attempt to set initial focus
450 struct sway_seat *current_seat = input_manager_current_seat(); 457 struct sway_seat *current_seat = input_manager_current_seat();
diff --git a/sway/main.c b/sway/main.c
index 0477bbc3..9ddbea81 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -16,6 +16,7 @@
16#include "sway/config.h" 16#include "sway/config.h"
17#include "sway/server.h" 17#include "sway/server.h"
18#include "sway/swaynag.h" 18#include "sway/swaynag.h"
19#include "sway/desktop/transaction.h"
19#include "sway/tree/root.h" 20#include "sway/tree/root.h"
20#include "sway/ipc-server.h" 21#include "sway/ipc-server.h"
21#include "ipc-client.h" 22#include "ipc-client.h"
@@ -389,6 +390,8 @@ int main(int argc, char **argv) {
389 config->active = true; 390 config->active = true;
390 load_swaybars(); 391 load_swaybars();
391 run_deferred_commands(); 392 run_deferred_commands();
393 run_deferred_bindings();
394 transaction_commit_dirty();
392 395
393 if (config->swaynag_config_errors.client != NULL) { 396 if (config->swaynag_config_errors.client != NULL) {
394 swaynag_show(&config->swaynag_config_errors); 397 swaynag_show(&config->swaynag_config_errors);