From 1627044c394e6629d854b7d976e8194a31ae9d90 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Sun, 31 Mar 2013 20:18:54 +0200 Subject: [PATCH] prefs: Fix binding remaining grabbed after clearing all strokes If a binding is updated with a clear set of strokes (effectively disabling it) we aren't signaling that the binding changed and thus the previous strokes will continue to be grabbed. This fixes that and tries to do a better effort at checking if the binding changed or not. https://bugzilla.gnome.org/show_bug.cgi?id=697000 --- src/core/prefs.c | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/src/core/prefs.c b/src/core/prefs.c index 308b94748..9026b8141 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -1758,10 +1758,11 @@ static gboolean update_binding (MetaKeyPref *binding, gchar **strokes) { + GSList *old_bindings, *a, *b; + gboolean changed; unsigned int keysym; unsigned int keycode; MetaVirtualModifier mods; - gboolean changed = FALSE; MetaKeyCombo *combo; int i; @@ -1769,13 +1770,9 @@ update_binding (MetaKeyPref *binding, "Binding \"%s\" has new GSettings value\n", binding->name); - /* Okay, so, we're about to provide a new list of key combos for this - * action. Delete any pre-existing list. - */ - g_slist_foreach (binding->bindings, (GFunc) g_free, NULL); - g_slist_free (binding->bindings); + old_bindings = binding->bindings; binding->bindings = NULL; - + for (i = 0; strokes && strokes[i]; i++) { keysym = 0; @@ -1810,8 +1807,6 @@ update_binding (MetaKeyPref *binding, * Changing the key in response to a modification could lead to cyclic calls. */ continue; } - - changed = TRUE; combo = g_malloc0 (sizeof (MetaKeyCombo)); combo->keysym = keysym; @@ -1826,6 +1821,34 @@ update_binding (MetaKeyPref *binding, binding->bindings = g_slist_reverse (binding->bindings); + a = old_bindings; + b = binding->bindings; + while (TRUE) + { + if ((!a && b) || (a && !b)) + { + changed = TRUE; + break; + } + else if (!a && !b) + { + changed = FALSE; + break; + } + else if (memcmp (a->data, b->data, sizeof (MetaKeyCombo)) != 0) + { + changed = TRUE; + break; + } + else + { + a = a->next; + b = b->next; + } + } + + g_slist_free_full (old_bindings, g_free); + return changed; }