[gnome-control-center/wip/gbsneto/new-keyboard-panel: 8/9] keyboard: bring back reverse item management



commit c555e71bc58b8d8f098f1078545560e2cf6c95ec
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Thu Jul 21 18:32:28 2016 -0300

    keyboard: bring back reverse item management
    
    In order to simplify the porting to the new UI, the
    reverse item functionality was removed. Now that all
    the necessary code landed, it is time to bring it back.
    
    This patch adds back the ability to manage reverse items.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=769063

 panels/keyboard/cc-keyboard-item.c    |   78 +++++++++++++++++++++++++++++++--
 panels/keyboard/cc-keyboard-manager.c |   71 ++++++++++++++++++-----------
 2 files changed, 118 insertions(+), 31 deletions(-)
---
diff --git a/panels/keyboard/cc-keyboard-item.c b/panels/keyboard/cc-keyboard-item.c
index abb8a3b..880df92 100644
--- a/panels/keyboard/cc-keyboard-item.c
+++ b/panels/keyboard/cc-keyboard-item.c
@@ -147,17 +147,53 @@ _set_binding (CcKeyboardItem *item,
               const char     *value,
              gboolean        set_backend)
 {
-  g_free (item->priv->binding);
-  item->priv->binding = g_strdup (value);
+  CcKeyboardItem *reverse;
+  gboolean enabled;
+
+  reverse = item->priv->reverse_item;
+  enabled = value && strlen (value) > 0;
+
+  g_clear_pointer (&item->priv->binding, g_free);
+  item->priv->binding = enabled ? g_strdup (value) : g_strdup ("");
+
   binding_from_string (item->priv->binding, &item->keyval,
                        &item->keycode, &item->mask);
 
+  /*
+   * Always treat the pair (item, reverse) as a unit: setting one also
+   * disables the other, disabling one up also sets the other.
+   */
+  if (reverse)
+    {
+      GdkModifierType reverse_mask;
+
+      reverse_mask = enabled ? item->mask ^ GDK_SHIFT_MASK : item->mask;
+
+      g_clear_pointer (&reverse->priv->binding, g_free);
+      if (enabled)
+        reverse->priv->binding = gtk_accelerator_name_with_keycode (NULL,
+                                                                    item->keyval,
+                                                                    item->keycode,
+                                                                    reverse_mask);
+
+      binding_from_string (reverse->priv->binding,
+                           &reverse->keyval,
+                           &reverse->keycode,
+                           &reverse->mask);
+    }
+
   if (set_backend == FALSE)
     return;
 
   settings_set_binding (item->settings, item->key, item->priv->binding);
 
   g_object_notify (G_OBJECT (item), "is-value-default");
+
+  if (reverse)
+    {
+      settings_set_binding (reverse->settings, reverse->key, reverse->priv->binding);
+      g_object_notify (G_OBJECT (reverse), "is-value-default");
+    }
 }
 
 static void
@@ -532,8 +568,32 @@ cc_keyboard_item_is_value_default (CcKeyboardItem *self)
     return TRUE;
 
   user_value = g_settings_get_user_value (self->settings, self->key);
-  is_value_default = user_value == NULL;
 
+  if (!user_value)
+    {
+      is_value_default = TRUE;
+      goto out;
+    }
+  else
+    {
+      GVariant *default_value;
+      const gchar *default_binding;
+
+      default_value = g_settings_get_default_value (self->settings, self->key);
+
+      if (g_variant_is_of_type (default_value, G_VARIANT_TYPE_STRING))
+        default_binding = g_variant_get_string (default_value, NULL);
+      else if (g_variant_is_of_type (default_value, G_VARIANT_TYPE_STRING_ARRAY))
+        default_binding = g_variant_get_strv (default_value, NULL)[0];
+      else
+        default_binding = "";
+
+      is_value_default = g_strcmp0 (default_binding, g_variant_get_string (user_value, NULL)) == 0;
+
+      g_clear_pointer (&default_value, g_variant_unref);
+    }
+
+out:
   g_clear_pointer (&user_value, g_variant_unref);
 
   return is_value_default;
@@ -548,11 +608,21 @@ cc_keyboard_item_is_value_default (CcKeyboardItem *self)
 void
 cc_keyboard_item_reset (CcKeyboardItem *self)
 {
+  CcKeyboardItem *reverse;
+
   g_return_if_fail (CC_IS_KEYBOARD_ITEM (self));
 
-  g_settings_reset (self->settings, self->key);
+  reverse = self->priv->reverse_item;
 
+  g_settings_reset (self->settings, self->key);
   g_object_notify (G_OBJECT (self), "is-value-default");
+
+  /* Also reset the reverse item */
+  if (reverse)
+    {
+      g_settings_reset (reverse->settings, reverse->key);
+      g_object_notify (G_OBJECT (reverse), "is-value-default");
+    }
 }
 
 /*
diff --git a/panels/keyboard/cc-keyboard-manager.c b/panels/keyboard/cc-keyboard-manager.c
index eb5e831..feb3cfc 100644
--- a/panels/keyboard/cc-keyboard-manager.c
+++ b/panels/keyboard/cc-keyboard-manager.c
@@ -96,35 +96,53 @@ get_binding_from_variant (GVariant *variant)
 }
 
 static gboolean
+is_shortcut_different (CcUniquenessData *data,
+                       CcKeyboardItem   *item)
+{
+  if (data->orig_item && cc_keyboard_item_equal (data->orig_item, item))
+    return FALSE;
+
+  if (data->new_keyval != 0)
+    {
+      if (data->new_keyval != item->keyval)
+        return TRUE;
+    }
+  else if (item->keyval != 0 || data->new_keycode != item->keycode)
+    {
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
 compare_keys_for_uniqueness (CcKeyboardItem   *current_item,
                              CcUniquenessData *data)
 {
-  CcKeyboardItem *item;
-
-  item = data->orig_item;
+  CcKeyboardItem *reverse_item;
 
   /* No conflict for: blanks, different modifiers or ourselves */
   if (!current_item ||
-      item == current_item ||
+      data->orig_item == current_item ||
       data->new_mask != current_item->mask)
     {
       return FALSE;
     }
 
-  if (item && cc_keyboard_item_equal (item, current_item))
-    goto out;
+  reverse_item = cc_keyboard_item_get_reverse_item (current_item);
 
-  if (data->new_keyval != 0)
-    {
-      if (data->new_keyval != current_item->keyval)
-          return FALSE;
-    }
-  else if (current_item->keyval != 0 || data->new_keycode != current_item->keycode)
-    {
-      return FALSE;
-    }
+  /* When the current item is the reversed shortcut of a main item, simply ignore it */
+  if (reverse_item && cc_keyboard_item_is_hidden (current_item))
+    return FALSE;
+
+  if (is_shortcut_different (data, current_item))
+    return FALSE;
 
-out:
+  /* Also check for the reverse item if any */
+  if (reverse_item && is_shortcut_different (data, reverse_item))
+    return FALSE;
+
+  /* No tests failed and we found a conflict */
   data->conflict_item = current_item;
 
   return TRUE;
@@ -903,6 +921,7 @@ cc_keyboard_manager_get_collision (CcKeyboardManager *self,
                                    gint               keycode)
 {
   CcUniquenessData data;
+  BindingGroupType i;
 
   g_return_val_if_fail (CC_IS_KEYBOARD_MANAGER (self), NULL);
 
@@ -912,22 +931,20 @@ cc_keyboard_manager_get_collision (CcKeyboardManager *self,
   data.new_keycode = keycode;
   data.conflict_item = NULL;
 
+  if (keyval == 0 && keycode == 0)
+    return NULL;
+
   /* Any number of shortcuts can be disabled */
-  if (keyval != 0 || keycode != 0)
+  for (i = BINDING_GROUP_SYSTEM; i <= BINDING_GROUP_USER && !data.conflict_item; i++)
     {
-      BindingGroupType i;
-
-      for (i = BINDING_GROUP_SYSTEM; i <= BINDING_GROUP_USER && !data.conflict_item; i++)
-        {
-          GHashTable *table;
+      GHashTable *table;
 
-          table = get_hash_for_group (self, i);
+      table = get_hash_for_group (self, i);
 
-          if (!table)
-            continue;
+      if (!table)
+        continue;
 
-          g_hash_table_find (table, (GHRFunc) check_for_uniqueness, &data);
-        }
+      g_hash_table_find (table, (GHRFunc) check_for_uniqueness, &data);
     }
 
   return data.conflict_item;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]