commit 9670ccee683ab985e89eb04302fb998c4161f2d6
parent 2b5bf78fafdf027624ca88e1f703bc9e577f4690
Author: Brian Ashworth <bosrsf04@gmail.com>
Date: Tue, 11 Jun 2019 21:41:02 -0400
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.
Diffstat:
6 files changed, 47 insertions(+), 2 deletions(-)
diff --git a/include/sway/config.h b/include/sway/config.h
@@ -559,6 +559,11 @@ bool read_config(FILE *file, struct sway_config *config,
void run_deferred_commands(void);
/**
+ * Run the binding commands that were deferred when initializing the inputs
+ */
+void run_deferred_bindings(void);
+
+/**
* Adds a warning entry to the swaynag instance used for errors.
*/
void config_add_swaynag_warning(char *fmt, ...);
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
@@ -78,6 +78,8 @@ struct sway_seat {
uint32_t last_button_serial;
+ list_t *deferred_bindings; // struct sway_binding
+
struct wl_listener focus_destroy;
struct wl_listener new_node;
struct wl_listener request_start_drag;
diff --git a/sway/commands/bind.c b/sway/commands/bind.c
@@ -559,8 +559,20 @@ struct cmd_results *cmd_unbindswitch(int argc, char **argv) {
* Execute the command associated to a binding
*/
void seat_execute_command(struct sway_seat *seat, struct sway_binding *binding) {
- sway_log(SWAY_DEBUG, "running command for binding: %s", binding->command);
+ if (!config->active) {
+ sway_log(SWAY_DEBUG, "deferring command for binding: %s",
+ binding->command);
+ struct sway_binding *deferred = calloc(1, sizeof(struct sway_binding));
+ if (!deferred) {
+ sway_log(SWAY_ERROR, "Failed to allocate deferred binding");
+ return;
+ }
+ memcpy(deferred, binding, sizeof(struct sway_binding));
+ list_add(seat->deferred_bindings, deferred);
+ return;
+ }
+ sway_log(SWAY_DEBUG, "running command for binding: %s", binding->command);
struct sway_container *con = NULL;
if (binding->type == BINDING_MOUSESYM
|| binding->type == BINDING_MOUSECODE) {
diff --git a/sway/config.c b/sway/config.c
@@ -644,7 +644,23 @@ void run_deferred_commands(void) {
list_free(res_list);
free(line);
}
- transaction_commit_dirty();
+}
+
+void run_deferred_bindings(void) {
+ struct sway_seat *seat;
+ wl_list_for_each(seat, &(server.input->seats), link) {
+ if (!seat->deferred_bindings->length) {
+ continue;
+ }
+ sway_log(SWAY_DEBUG, "Running deferred bindings for seat %s",
+ seat->wlr_seat->name);
+ while (seat->deferred_bindings->length) {
+ struct sway_binding *binding = seat->deferred_bindings->items[0];
+ seat_execute_command(seat, binding);
+ list_del(seat->deferred_bindings, 0);
+ free_sway_binding(binding);
+ }
+ }
}
// get line, with backslash continuation
diff --git a/sway/input/seat.c b/sway/input/seat.c
@@ -9,6 +9,7 @@
#include <wlr/types/wlr_primary_selection.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include "config.h"
+#include "list.h"
#include "log.h"
#include "sway/desktop.h"
#include "sway/input/cursor.h"
@@ -51,6 +52,10 @@ void seat_destroy(struct sway_seat *seat) {
wl_list_remove(&seat->request_set_primary_selection.link);
wl_list_remove(&seat->link);
wlr_seat_destroy(seat->wlr_seat);
+ for (int i = 0; i < seat->deferred_bindings->length; i++) {
+ free_sway_binding(seat->deferred_bindings->items[i]);
+ }
+ list_free(seat->deferred_bindings);
free(seat->prev_workspace_name);
free(seat);
}
@@ -445,6 +450,8 @@ struct sway_seat *seat_create(const char *seat_name) {
root_for_each_workspace(collect_focus_workspace_iter, seat);
root_for_each_container(collect_focus_container_iter, seat);
+ seat->deferred_bindings = create_list();
+
if (!wl_list_empty(&server.input->seats)) {
// Since this is not the first seat, attempt to set initial focus
struct sway_seat *current_seat = input_manager_current_seat();
diff --git a/sway/main.c b/sway/main.c
@@ -16,6 +16,7 @@
#include "sway/config.h"
#include "sway/server.h"
#include "sway/swaynag.h"
+#include "sway/desktop/transaction.h"
#include "sway/tree/root.h"
#include "sway/ipc-server.h"
#include "ipc-client.h"
@@ -389,6 +390,8 @@ int main(int argc, char **argv) {
config->active = true;
load_swaybars();
run_deferred_commands();
+ run_deferred_bindings();
+ transaction_commit_dirty();
if (config->swaynag_config_errors.client != NULL) {
swaynag_show(&config->swaynag_config_errors);