From 48bc984c76b21430f719fbf34ed4da30247236d4 Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Wed, 15 Nov 2023 23:19:55 +0100 Subject: [PATCH] input/keyboard: Skip configure on same config sway_keyboard_configure does a lot of keyboard setup, including loading the keymap (possibly twice in case of fallback), serializing both old and new keymap to compare them with a strcmp, and updating state that leads to events for all related clients. This function is called a lot - output configuration will call it n_outputs x n_keyboard_devices times. Avoid doing work if the configuration for a particular keyboard has not actually changed. --- include/sway/config.h | 2 ++ include/sway/input/keyboard.h | 2 ++ sway/config/input.c | 5 +++++ sway/input/keyboard.c | 7 +++++++ 4 files changed, 16 insertions(+) diff --git a/include/sway/config.h b/include/sway/config.h index f9da19675..a754ae746 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -189,6 +189,8 @@ struct input_config { bool capturable; struct wlr_box region; + + uint64_t seq_id; }; /** diff --git a/include/sway/input/keyboard.h b/include/sway/input/keyboard.h index 571d9e6fa..9b2687bef 100644 --- a/include/sway/input/keyboard.h +++ b/include/sway/input/keyboard.h @@ -69,6 +69,8 @@ struct sway_keyboard { struct wl_event_source *key_repeat_source; struct sway_binding *repeat_binding; + + uint64_t last_input_config; }; struct sway_keyboard_group { diff --git a/sway/config/input.c b/sway/config/input.c index 44c2be289..4ce1b9503 100644 --- a/sway/config/input.c +++ b/sway/config/input.c @@ -6,12 +6,16 @@ #include "sway/input/keyboard.h" #include "log.h" +static uint64_t input_config_sequence = 0; + struct input_config *new_input_config(const char* identifier) { struct input_config *input = calloc(1, sizeof(struct input_config)); if (!input) { sway_log(SWAY_DEBUG, "Unable to allocate input config"); return NULL; } + input->seq_id = input_config_sequence++; + sway_log(SWAY_DEBUG, "new_input_config(%s)", identifier); if (!(input->identifier = strdup(identifier))) { free(input); @@ -182,6 +186,7 @@ void merge_input_config(struct input_config *dst, struct input_config *src) { tool_merge_outer:; } + dst->seq_id = input_config_sequence++; } static bool validate_xkb_merge(struct input_config *dest, diff --git a/sway/input/keyboard.c b/sway/input/keyboard.c index 8927287fb..fc45746f0 100644 --- a/sway/input/keyboard.c +++ b/sway/input/keyboard.c @@ -969,6 +969,11 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) { return; } + if (!config->reloading && keyboard->last_input_config == input_config->seq_id) { + // We have been here before, so bail early + return; + } + struct xkb_keymap *keymap = sway_keyboard_compile_keymap(input_config, NULL); if (!keymap) { sway_log(SWAY_ERROR, "Failed to compile keymap. Attempting defaults"); @@ -1068,6 +1073,8 @@ void sway_keyboard_configure(struct sway_keyboard *keyboard) { &keyboard->keyboard_modifiers); keyboard->keyboard_modifiers.notify = handle_keyboard_modifiers; + keyboard->last_input_config = input_config->seq_id; + if (keymap_changed) { ipc_event_input("xkb_keymap", keyboard->seat_device->input_device);