diff --git a/ChangeLog b/ChangeLog index 305370818f..62ffc23f12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +Fri Mar 22 11:29:11 2002 Owen Taylor + + Partial fix for problem where keypad keys acted + as shift-arrows in an entry rather than arrows (#74327) + + * gtk/gtkkeyhash.c (_gtk_key_hash_lookup): Sort lookup + results by number of modifiers in the entry. Fixes + problem where if a key matched both modified and unmodified + key bindings ... e.g., the distinguishing key binding + was consumed, then it was random which was used. + + * gtk/gtkbindings.c (gtk_binding_entries_sort_patterns): + Catch the case where there are multiple entries from the + same bindingset (with different modifiers), and use only + the first entry, which, with the change in _gtk_key_hash_lookup() + will be the preferred value. + Fri Mar 22 10:56:19 2002 Owen Taylor * gtk/gtkaccelmap.c (gtk_accel_map_save_fd): Fix memory diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 305370818f..62ffc23f12 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,20 @@ +Fri Mar 22 11:29:11 2002 Owen Taylor + + Partial fix for problem where keypad keys acted + as shift-arrows in an entry rather than arrows (#74327) + + * gtk/gtkkeyhash.c (_gtk_key_hash_lookup): Sort lookup + results by number of modifiers in the entry. Fixes + problem where if a key matched both modified and unmodified + key bindings ... e.g., the distinguishing key binding + was consumed, then it was random which was used. + + * gtk/gtkbindings.c (gtk_binding_entries_sort_patterns): + Catch the case where there are multiple entries from the + same bindingset (with different modifiers), and use only + the first entry, which, with the change in _gtk_key_hash_lookup() + will be the preferred value. + Fri Mar 22 10:56:19 2002 Owen Taylor * gtk/gtkaccelmap.c (gtk_accel_map_save_fd): Fix memory diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2 index 305370818f..62ffc23f12 100644 --- a/ChangeLog.pre-2-2 +++ b/ChangeLog.pre-2-2 @@ -1,3 +1,20 @@ +Fri Mar 22 11:29:11 2002 Owen Taylor + + Partial fix for problem where keypad keys acted + as shift-arrows in an entry rather than arrows (#74327) + + * gtk/gtkkeyhash.c (_gtk_key_hash_lookup): Sort lookup + results by number of modifiers in the entry. Fixes + problem where if a key matched both modified and unmodified + key bindings ... e.g., the distinguishing key binding + was consumed, then it was random which was used. + + * gtk/gtkbindings.c (gtk_binding_entries_sort_patterns): + Catch the case where there are multiple entries from the + same bindingset (with different modifiers), and use only + the first entry, which, with the change in _gtk_key_hash_lookup() + will be the preferred value. + Fri Mar 22 10:56:19 2002 Owen Taylor * gtk/gtkaccelmap.c (gtk_accel_map_save_fd): Fix memory diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 305370818f..62ffc23f12 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,20 @@ +Fri Mar 22 11:29:11 2002 Owen Taylor + + Partial fix for problem where keypad keys acted + as shift-arrows in an entry rather than arrows (#74327) + + * gtk/gtkkeyhash.c (_gtk_key_hash_lookup): Sort lookup + results by number of modifiers in the entry. Fixes + problem where if a key matched both modified and unmodified + key bindings ... e.g., the distinguishing key binding + was consumed, then it was random which was used. + + * gtk/gtkbindings.c (gtk_binding_entries_sort_patterns): + Catch the case where there are multiple entries from the + same bindingset (with different modifiers), and use only + the first entry, which, with the change in _gtk_key_hash_lookup() + will be the preferred value. + Fri Mar 22 10:56:19 2002 Owen Taylor * gtk/gtkaccelmap.c (gtk_accel_map_save_fd): Fix memory diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 305370818f..62ffc23f12 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,20 @@ +Fri Mar 22 11:29:11 2002 Owen Taylor + + Partial fix for problem where keypad keys acted + as shift-arrows in an entry rather than arrows (#74327) + + * gtk/gtkkeyhash.c (_gtk_key_hash_lookup): Sort lookup + results by number of modifiers in the entry. Fixes + problem where if a key matched both modified and unmodified + key bindings ... e.g., the distinguishing key binding + was consumed, then it was random which was used. + + * gtk/gtkbindings.c (gtk_binding_entries_sort_patterns): + Catch the case where there are multiple entries from the + same bindingset (with different modifiers), and use only + the first entry, which, with the change in _gtk_key_hash_lookup() + will be the preferred value. + Fri Mar 22 10:56:19 2002 Owen Taylor * gtk/gtkaccelmap.c (gtk_accel_map_save_fd): Fix memory diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 305370818f..62ffc23f12 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,20 @@ +Fri Mar 22 11:29:11 2002 Owen Taylor + + Partial fix for problem where keypad keys acted + as shift-arrows in an entry rather than arrows (#74327) + + * gtk/gtkkeyhash.c (_gtk_key_hash_lookup): Sort lookup + results by number of modifiers in the entry. Fixes + problem where if a key matched both modified and unmodified + key bindings ... e.g., the distinguishing key binding + was consumed, then it was random which was used. + + * gtk/gtkbindings.c (gtk_binding_entries_sort_patterns): + Catch the case where there are multiple entries from the + same bindingset (with different modifiers), and use only + the first entry, which, with the change in _gtk_key_hash_lookup() + will be the preferred value. + Fri Mar 22 10:56:19 2002 Owen Taylor * gtk/gtkaccelmap.c (gtk_accel_map_save_fd): Fix memory diff --git a/gtk/gtkbindings.c b/gtk/gtkbindings.c index abf473c465..6f1fed57a5 100644 --- a/gtk/gtkbindings.c +++ b/gtk/gtkbindings.c @@ -954,8 +954,18 @@ gtk_binding_entries_sort_patterns (GSList *entries, gboolean is_release) { GSList *patterns; + GSList *tmp_list; patterns = NULL; + for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next) + { + GtkBindingEntry *entry = tmp_list->data; + GtkBindingSet *binding_set; + + binding_set = entry->binding_set; + binding_set->current = NULL; + } + for (; entries; entries = entries->next) { GtkBindingEntry *entry = entries->data; @@ -966,6 +976,9 @@ gtk_binding_entries_sort_patterns (GSList *entries, continue; binding_set = entry->binding_set; + + if (binding_set->current) + continue; binding_set->current = entry; switch (path_id) diff --git a/gtk/gtkkeyhash.c b/gtk/gtkkeyhash.c index bbf113926a..c08f018402 100644 --- a/gtk/gtkkeyhash.c +++ b/gtk/gtkkeyhash.c @@ -242,6 +242,46 @@ _gtk_key_hash_remove_entry (GtkKeyHash *key_hash, } } +static gint +lookup_result_compare (gconstpointer a, + gconstpointer b) +{ + const GtkKeyHashEntry *entry_a = a; + const GtkKeyHashEntry *entry_b = b; + guint modifiers; + + gint n_bits_a = 0; + gint n_bits_b = 0; + + modifiers = entry_a->modifiers; + while (modifiers) + { + if (modifiers & 1) + n_bits_a++; + modifiers >>= 1; + } + + modifiers = entry_b->modifiers; + while (modifiers) + { + if (modifiers & 1) + n_bits_b++; + modifiers >>= 1; + } + + return n_bits_a < n_bits_b ? -1 : (n_bits_a == n_bits_b ? 0 : 1); + +} + +/* Sort a list of results so that matches with less modifiers come + * before matches with more modifiers + */ +static GSList * +sort_lookup_results (GSList *slist) +{ + return g_slist_sort (slist, lookup_result_compare); +} + /** * _gtk_key_hash_lookup: * @key_hash: a #GtkKeyHash @@ -250,7 +290,8 @@ _gtk_key_hash_remove_entry (GtkKeyHash *key_hash, * @group: group field from a #GdkEventKey * * Looks up the best matching entry or entries in the hash table for - * a given event. + * a given event. The results are sorted so that entries with less + * modifiers come before entries with more modifiers. * * Return value: A #GSList of all matching entries. If there were exact * matches, they are returned, otherwise all fuzzy matches are @@ -328,7 +369,7 @@ _gtk_key_hash_lookup (GtkKeyHash *key_hash, } } - return results; + return sort_lookup_results (results); } /** @@ -339,7 +380,8 @@ _gtk_key_hash_lookup (GtkKeyHash *key_hash, * Looks up the best matching entry or entries in the hash table for a * given keyval/modifiers pair. It's better to use * _gtk_key_hash_lookup() if you have the original #GdkEventKey - * available. + * available. The results are sorted so that entries with less + * modifiers come before entries with more modifiers. * * Return value: A #GSList of all matching entries. **/ @@ -377,5 +419,5 @@ _gtk_key_hash_lookup_keyval (GtkKeyHash *key_hash, g_free (keys); - return results; + return sort_lookup_results (results); }