diff --git a/include/sway/config.h b/include/sway/config.h index 81e9c382..e75b0664 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -30,7 +30,7 @@ struct sway_binding { bool release; bool locked; bool bindcode; - list_t *keys; + list_t *keys; // sorted in ascending order uint32_t modifiers; char *command; }; diff --git a/sway/commands/bind.c b/sway/commands/bind.c index d0e3e22f..821f9cd1 100644 --- a/sway/commands/bind.c +++ b/sway/commands/bind.c @@ -32,7 +32,7 @@ void free_sway_binding(struct sway_binding *binding) { * Note that keyboard layout is not considered, so the bindings might actually * not be equivalent on some layouts. */ -bool binding_key_compare(struct sway_binding *binding_a, +static bool binding_key_compare(struct sway_binding *binding_a, struct sway_binding *binding_b) { if (binding_a->release != binding_b->release) { return false; @@ -50,18 +50,12 @@ bool binding_key_compare(struct sway_binding *binding_a, return false; } + // Keys are sorted int keys_len = binding_a->keys->length; for (int i = 0; i < keys_len; ++i) { - uint32_t key_a = *(uint32_t*)binding_a->keys->items[i]; - bool found = false; - for (int j = 0; j < keys_len; ++j) { - uint32_t key_b = *(uint32_t*)binding_b->keys->items[j]; - if (key_b == key_a) { - found = true; - break; - } - } - if (!found) { + uint32_t key_a = *(uint32_t *)binding_a->keys->items[i]; + uint32_t key_b = *(uint32_t *)binding_b->keys->items[i]; + if (key_a != key_b) { return false; } } @@ -69,6 +63,12 @@ bool binding_key_compare(struct sway_binding *binding_a, return true; } +static int key_qsort_cmp(const void *keyp_a, const void *keyp_b) { + uint32_t key_a = **(uint32_t **)keyp_a; + uint32_t key_b = **(uint32_t **)keyp_b; + return (key_a < key_b) ? -1 : ((key_a > key_b) ? 1 : 0); +} + static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv, bool bindcode) { const char *bindtype = bindcode ? "bindcode" : "bindsym"; @@ -169,6 +169,9 @@ static struct cmd_results *cmd_bindsym_or_bindcode(int argc, char **argv, free_flat_list(split); binding->order = binding_order++; + // sort ascending + list_qsort(binding->keys, key_qsort_cmp); + list_t *mode_bindings; if (bindcode) { mode_bindings = config->current_mode->keycode_bindings;