[gnome-builder/wip/chergert/merge-shortcuts] shortcuts: add basic CoW support for parent themes



commit b7e86c4d1a60f28dc6e9dd412f18dc36067619fd
Author: Christian Hergert <chergert redhat com>
Date:   Fri May 26 17:00:50 2017 -0700

    shortcuts: add basic CoW support for parent themes

 doc/plugins/keybindings.rst                |    2 -
 libide/shortcuts/ide-shortcut-controller.c |   77 +++++++++++++++++++++++++---
 libide/shortcuts/ide-shortcut-manager.c    |   30 +++++++++++
 libide/shortcuts/ide-shortcut-manager.h    |    2 +
 4 files changed, 101 insertions(+), 10 deletions(-)
---
diff --git a/doc/plugins/keybindings.rst b/doc/plugins/keybindings.rst
index 6da9dc4..b8609bf 100644
--- a/doc/plugins/keybindings.rst
+++ b/doc/plugins/keybindings.rst
@@ -119,13 +119,11 @@ Note that some key themes have more complex "modal" contexts (such as Vim).
 
    <?xml version="1.0" encoding="UTF-8"?>
    <theme name="default">
-
      <!-- Only map command when focused in an GtkEntry -->
      <context name="GtkEntry">
        <shortcut accelerator="<Control><Shift>r"
                      command="org.gnome.builder.commands.my-command"/>
      </context>
-
    </theme>
 
 
diff --git a/libide/shortcuts/ide-shortcut-controller.c b/libide/shortcuts/ide-shortcut-controller.c
index 3c7932e..b9e6b6d 100644
--- a/libide/shortcuts/ide-shortcut-controller.c
+++ b/libide/shortcuts/ide-shortcut-controller.c
@@ -114,6 +114,19 @@ static GQuark      controller_quark;
 static void ide_shortcut_controller_connect    (IdeShortcutController *self);
 static void ide_shortcut_controller_disconnect (IdeShortcutController *self);
 
+static IdeShortcutManager *
+ide_shortcut_controller_get_manager (IdeShortcutController *self)
+{
+  g_assert (IDE_IS_SHORTCUT_CONTROLLER (self));
+
+
+  /* TODO: We might want to locate the manager from the root controller
+   *       to allow for non-default shortcut managers.
+   */
+
+  return ide_shortcut_manager_get_default ();
+}
+
 static gboolean
 ide_shortcut_controller_is_mapped (IdeShortcutController *self)
 {
@@ -221,17 +234,20 @@ static void
 ide_shortcut_controller_disconnect (IdeShortcutController *self)
 {
   IdeShortcutControllerPrivate *priv = ide_shortcut_controller_get_instance_private (self);
+  IdeShortcutManager *manager;
 
   g_assert (IDE_IS_SHORTCUT_CONTROLLER (self));
   g_assert (GTK_IS_WIDGET (priv->widget));
 
+  manager = ide_shortcut_controller_get_manager (self);
+
   g_signal_handler_disconnect (priv->widget, priv->widget_destroy_handler);
   priv->widget_destroy_handler = 0;
 
   g_signal_handler_disconnect (priv->widget, priv->hierarchy_changed_handler);
   priv->hierarchy_changed_handler = 0;
 
-  g_signal_handler_disconnect (ide_shortcut_manager_get_default (), priv->manager_changed_handler);
+  g_signal_handler_disconnect (manager, priv->manager_changed_handler);
   priv->manager_changed_handler = 0;
 }
 
@@ -239,10 +255,13 @@ static void
 ide_shortcut_controller_connect (IdeShortcutController *self)
 {
   IdeShortcutControllerPrivate *priv = ide_shortcut_controller_get_instance_private (self);
+  IdeShortcutManager *manager;
 
   g_assert (IDE_IS_SHORTCUT_CONTROLLER (self));
   g_assert (GTK_IS_WIDGET (priv->widget));
 
+  manager = ide_shortcut_controller_get_manager (self);
+
   g_clear_pointer (&priv->current_chord, ide_shortcut_chord_free);
   g_clear_object (&priv->context);
 
@@ -259,7 +278,7 @@ ide_shortcut_controller_connect (IdeShortcutController *self)
                               self);
 
   priv->manager_changed_handler =
-    g_signal_connect_swapped (ide_shortcut_manager_get_default (),
+    g_signal_connect_swapped (manager,
                               "changed",
                               G_CALLBACK (ide_shortcut_controller_on_manager_changed),
                               self);
@@ -331,7 +350,7 @@ ide_shortcut_controller_real_set_context_named (IdeShortcutController *self,
   g_return_if_fail (IDE_IS_SHORTCUT_CONTROLLER (self));
   g_return_if_fail (name != NULL);
 
-  manager = ide_shortcut_manager_get_default ();
+  manager = ide_shortcut_controller_get_manager (self);
   theme = ide_shortcut_manager_get_theme (manager);
   context = ide_shortcut_theme_find_context_by_name (theme, name);
 
@@ -565,7 +584,7 @@ ide_shortcut_controller_get_context (IdeShortcutController *self)
       IdeShortcutManager *manager;
       IdeShortcutTheme *theme;
 
-      manager = ide_shortcut_manager_get_default ();
+      manager = ide_shortcut_controller_get_manager (self);
       theme = ide_shortcut_manager_get_theme (manager);
 
       /*
@@ -579,6 +598,43 @@ ide_shortcut_controller_get_context (IdeShortcutController *self)
   return priv->context;
 }
 
+static IdeShortcutContext *
+ide_shortcut_controller_get_parent_context (IdeShortcutController *self)
+{
+  IdeShortcutControllerPrivate *priv = ide_shortcut_controller_get_instance_private (self);
+  IdeShortcutManager *manager;
+  IdeShortcutTheme *theme;
+  IdeShortcutTheme *parent;
+  const gchar *name = NULL;
+  const gchar *parent_name = NULL;
+
+  g_assert (IDE_IS_SHORTCUT_CONTROLLER (self));
+
+  manager = ide_shortcut_controller_get_manager (self);
+
+  theme = ide_shortcut_manager_get_theme (manager);
+  if (theme == NULL)
+    return NULL;
+
+  parent_name = ide_shortcut_theme_get_parent_name (theme);
+  if (parent_name == NULL)
+    return NULL;
+
+  parent = ide_shortcut_manager_get_theme_by_name (manager, parent_name);
+  if (parent == NULL)
+    return NULL;
+
+  if (priv->context != NULL)
+    {
+      name = ide_shortcut_context_get_name (priv->context);
+
+      if (name != NULL)
+        return ide_shortcut_theme_find_context_by_name (theme, name);
+    }
+
+  return ide_shortcut_theme_find_default_context (theme, priv->widget);
+}
+
 static IdeShortcutMatch
 ide_shortcut_controller_process (IdeShortcutController  *self,
                                  const IdeShortcutChord *chord)
@@ -597,13 +653,18 @@ ide_shortcut_controller_process (IdeShortcutController  *self,
     return IDE_SHORTCUT_MATCH_NONE;
 
   /* Try to activate our current context */
-  context = ide_shortcut_controller_get_context (self);
-  if (match == IDE_SHORTCUT_MATCH_NONE && context != NULL)
+  if (match == IDE_SHORTCUT_MATCH_NONE &&
+      NULL != (context = ide_shortcut_controller_get_context (self)))
+    match = ide_shortcut_context_activate (context, priv->widget, chord);
+
+  /* If we didn't get a match, locate the context within the parent theme */
+  if (match == IDE_SHORTCUT_MATCH_NONE &&
+      NULL != (context = ide_shortcut_controller_get_parent_context (self)))
     match = ide_shortcut_context_activate (context, priv->widget, chord);
 
   /* If we didn't find a match, try our command context */
-  context = priv->command_context;
-  if (match == IDE_SHORTCUT_MATCH_NONE && context != NULL)
+  if (match == IDE_SHORTCUT_MATCH_NONE &&
+      NULL != (context = priv->command_context))
     match = ide_shortcut_context_activate (context, priv->widget, chord);
 
   /* Try to activate one of our descendant controllers */
diff --git a/libide/shortcuts/ide-shortcut-manager.c b/libide/shortcuts/ide-shortcut-manager.c
index 4f23add..e86b656 100644
--- a/libide/shortcuts/ide-shortcut-manager.c
+++ b/libide/shortcuts/ide-shortcut-manager.c
@@ -999,3 +999,33 @@ ide_shortcut_manager_add_shortcut_entries (IdeShortcutManager     *self,
                                         g_dgettext (translation_domain, entry->subtitle));
     }
 }
+
+/**
+ * ide_shortcut_manager_get_theme_by_name:
+ * @self: a #IdeShortcutManager
+ *
+ * Locates a theme by the name of the theme.
+ *
+ * Returns: (transfer none) (nullable): A #IdeShortcutTheme or %NULL.
+ */
+IdeShortcutTheme *
+ide_shortcut_manager_get_theme_by_name (IdeShortcutManager *self,
+                                        const gchar        *theme_name)
+{
+  IdeShortcutManagerPrivate *priv = ide_shortcut_manager_get_instance_private (self);
+
+  g_return_val_if_fail (IDE_IS_SHORTCUT_MANAGER (self), NULL);
+  g_return_val_if_fail (theme_name != NULL, NULL);
+
+  for (guint i = 0; i < priv->themes->len; i++)
+    {
+      IdeShortcutTheme *theme = g_ptr_array_index (priv->themes, i);
+
+      g_assert (IDE_IS_SHORTCUT_THEME (theme));
+
+      if (g_strcmp0 (theme_name, ide_shortcut_theme_get_name (theme)) == 0)
+        return theme;
+    }
+
+  return NULL;
+}
diff --git a/libide/shortcuts/ide-shortcut-manager.h b/libide/shortcuts/ide-shortcut-manager.h
index 181e2e4..dbb3e1e 100644
--- a/libide/shortcuts/ide-shortcut-manager.h
+++ b/libide/shortcuts/ide-shortcut-manager.h
@@ -65,6 +65,8 @@ void                ide_shortcut_manager_set_theme               (IdeShortcutMan
 const gchar        *ide_shortcut_manager_get_theme_name          (IdeShortcutManager     *self);
 void                ide_shortcut_manager_set_theme_name          (IdeShortcutManager     *self,
                                                                   const gchar            *theme_name);
+IdeShortcutTheme   *ide_shortcut_manager_get_theme_by_name       (IdeShortcutManager     *self,
+                                                                  const gchar            *theme_name);
 gboolean            ide_shortcut_manager_handle_event            (IdeShortcutManager     *self,
                                                                   const GdkEventKey      *event,
                                                                   GtkWidget              *toplevel);


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