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.
This commit is contained in:
Kenny Levinsen 2023-11-15 23:19:55 +01:00
parent 020a572ed6
commit 48bc984c76
4 changed files with 16 additions and 0 deletions

View file

@ -189,6 +189,8 @@ struct input_config {
bool capturable;
struct wlr_box region;
uint64_t seq_id;
};
/**

View file

@ -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 {

View file

@ -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,

View file

@ -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);