From 9d50f88ceffc44f5ce0b83cc060bbae649ce898b Mon Sep 17 00:00:00 2001 From: taiyu Date: Tue, 24 Nov 2015 00:30:02 -0800 Subject: [PATCH] fix list sorting --- common/list.c | 8 +++++++- sway/commands.c | 6 +++--- sway/config.c | 22 ++++++++++++---------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/common/list.c b/common/list.c index 310296d87..d6f6f2eab 100644 --- a/common/list.c +++ b/common/list.c @@ -50,8 +50,14 @@ void list_cat(list_t *list, list_t *source) { } } +// pass the pointer of the object we care about to the comparison function +static int list_cmp(const void *l, const void *r, void *_cmp) { + int (*cmp)(const void *, const void *) = _cmp; + return cmp(*(void**)l, *(void**)r); +} + void list_sort(list_t *list, int compare(const void *left, const void *right)) { - qsort(list->items, list->length, sizeof(void *), compare); + qsort_r(list->items, list->length, sizeof(void *), list_cmp, compare); } int list_seq_find(list_t *list, int compare(const void *item, const void *data), const void *data) { diff --git a/sway/commands.c b/sway/commands.c index 5b3b1d0fb..f6d56bb4e 100644 --- a/sway/commands.c +++ b/sway/commands.c @@ -1128,9 +1128,9 @@ static struct cmd_results *cmd_scratchpad(int argc, char **argv) { // sort in order of longest->shortest static int compare_set(const void *_l, const void *_r) { - struct sway_variable * const *l = _l; - struct sway_variable * const *r = _r; - return strlen((*r)->name) - strlen((*l)->name); + struct sway_variable const *l = _l; + struct sway_variable const *r = _r; + return strlen(r->name) - strlen(l->name); } static struct cmd_results *cmd_set(int argc, char **argv) { diff --git a/sway/config.c b/sway/config.c index d70c016a3..f2523c1f6 100644 --- a/sway/config.c +++ b/sway/config.c @@ -387,18 +387,20 @@ int workspace_output_cmp_workspace(const void *a, const void *b) { int sway_binding_cmp_keys(const void *a, const void *b) { const struct sway_binding *binda = a, *bindb = b; - if (binda->modifiers > bindb->modifiers) { - return 1; - } else if (binda->modifiers < bindb->modifiers) { - return -1; - } - - if (binda->keys->length > bindb->keys->length) { - return 1; - } else if (binda->keys->length < bindb->keys->length) { - return -1; + // Count keys pressed for this binding. important so we check long before + // short ones. for example mod+a+b before mod+a + unsigned int moda = 0, modb = 0, i; + + // Count how any modifiers are pressed + for (i = 0; i < 8 * sizeof(binda->modifiers); ++i) { + moda += (binda->modifiers & 1 << i) != 0; + modb += (bindb->modifiers & 1 << i) != 0; + } + if (bindb->keys->length + modb != binda->keys->length + moda) { + return (bindb->keys->length + modb) - (binda->keys->length + moda); } + // Otherwise compare keys for (int i = 0; i < binda->keys->length; i++) { xkb_keysym_t *ka = binda->keys->items[i], *kb = bindb->keys->items[i];