[libdazzle] shortcuts: add phase tracking to controller commands



commit 047c9659a8551d29bed41bf9b2401000c5f5e8c2
Author: Christian Hergert <chergert redhat com>
Date:   Tue Jul 18 15:40:36 2017 -0700

    shortcuts: add phase tracking to controller commands
    
    This allows specifying a phase for controller commands. This is useful when you
    want some actions/callbacks/etc to happen within a certain dispatch phase of
    the shortcut activation.
    
    For example, you might want certainly global shortcuts to never be overridable,
    but others to be captured by a webview.

 examples/app/example-window.c           |    6 ++--
 src/shortcuts/dzl-shortcut-controller.c |   44 ++++++++++++++++++++++--------
 src/shortcuts/dzl-shortcut-controller.h |    3 ++
 src/shortcuts/dzl-shortcut-manager.c    |    3 +-
 src/shortcuts/dzl-shortcut-private.h    |    1 +
 tests/test-shortcut-theme.c             |    2 +-
 tests/test-shortcuts.c                  |    8 +++--
 7 files changed, 47 insertions(+), 20 deletions(-)
---
diff --git a/examples/app/example-window.c b/examples/app/example-window.c
index 7c9a73e..253a9f8 100644
--- a/examples/app/example-window.c
+++ b/examples/app/example-window.c
@@ -175,9 +175,9 @@ example_window_init (ExampleWindow *self)
 
   controller = dzl_shortcut_controller_find (GTK_WIDGET (self));
 
-  dzl_shortcut_controller_add_command_action (controller, "com.example.window.NewDoc", NULL, 
"win.new-document");
-  dzl_shortcut_controller_add_command_action (controller, "com.example.window.CloseDoc", NULL, 
"win.close-document");
-  dzl_shortcut_controller_add_command_action (controller, "com.example.window.Fullscreen", NULL, 
"win.fullscreen");
+  dzl_shortcut_controller_add_command_action (controller, "com.example.window.NewDoc", NULL, 0, 
"win.new-document");
+  dzl_shortcut_controller_add_command_action (controller, "com.example.window.CloseDoc", NULL, 0, 
"win.close-document");
+  dzl_shortcut_controller_add_command_action (controller, "com.example.window.Fullscreen", NULL, 0, 
"win.fullscreen");
 
   g_signal_connect_swapped (self,
                             "key-press-event",
diff --git a/src/shortcuts/dzl-shortcut-controller.c b/src/shortcuts/dzl-shortcut-controller.c
index 6202272..c2b4a1e 100644
--- a/src/shortcuts/dzl-shortcut-controller.c
+++ b/src/shortcuts/dzl-shortcut-controller.c
@@ -880,6 +880,13 @@ _dzl_shortcut_controller_handle (DzlShortcutController  *self,
       theme = dzl_shortcut_manager_get_theme (manager);
       theme_match = _dzl_shortcut_theme_match (theme, phase, chord, &chain);
 
+      /* If this chain doesn't match our phase, ignore it */
+      if (chain != NULL && chain->phase != phase)
+        {
+          theme_match = DZL_SHORTCUT_MATCH_NONE;
+          chain = NULL;
+        }
+
       if (theme_match == DZL_SHORTCUT_MATCH_EQUAL)
         dzl_shortcut_closure_chain_execute (chain, priv->widget);
 
@@ -962,6 +969,7 @@ static void
 dzl_shortcut_controller_add_command (DzlShortcutController   *self,
                                      const gchar             *command_id,
                                      const gchar             *default_accel,
+                                     DzlShortcutPhase         phase,
                                      DzlShortcutClosureChain *chain)
 {
   DzlShortcutControllerPrivate *priv = dzl_shortcut_controller_get_instance_private (self);
@@ -972,33 +980,43 @@ dzl_shortcut_controller_add_command (DzlShortcutController   *self,
   g_assert (DZL_IS_SHORTCUT_CONTROLLER (self));
   g_assert (command_id != NULL);
   g_assert (chain != NULL);
+  g_assert (phase <= DZL_SHORTCUT_PHASE_BUBBLE);
 
+  /* Always use interned strings for command ids */
   command_id = g_intern_string (command_id);
 
+  /*
+   * Set the phase on the closure chain so we know what phase we are allowed
+   * to execute the chain within during capture/dispatch/bubble.
+   */
+  chain->phase = phase;
+
+  /* Add the closure chain to our set of commands. */
   if (priv->commands == NULL)
     priv->commands = g_hash_table_new_full (NULL, NULL, NULL,
                                             (GDestroyNotify)dzl_shortcut_closure_chain_free);
-
   g_hash_table_insert (priv->commands, (gpointer)command_id, chain);
 
-  if (priv->commands_table == NULL)
-    priv->commands_table = dzl_shortcut_chord_table_new ();
-
+  /* If an accel was provided, we need to register it in various places */
   if (default_accel != NULL)
     {
+      /* Make sure this is a valid accelerator */
       chord = dzl_shortcut_chord_new_from_string (default_accel);
 
       if (chord != NULL)
         {
+          /* Add the chord to our chord table for lookups */
+          if (priv->commands_table == NULL)
+            priv->commands_table = dzl_shortcut_chord_table_new ();
           dzl_shortcut_chord_table_add (priv->commands_table, chord, (gpointer)command_id);
+
+          /* Set the value in the theme so it can have overrides by users */
           manager = dzl_shortcut_controller_get_manager (self);
           theme = _dzl_shortcut_manager_get_internal_theme (manager);
           dzl_shortcut_theme_set_chord_for_command (theme, command_id, chord);
-
-#if 0
-          g_print ("Added %s for command %s\n", default_accel, command_id);
-#endif
         }
+      else
+        g_warning ("\"%s\" is not a valid accelerator chord", default_accel);
     }
 }
 
@@ -1006,6 +1024,7 @@ void
 dzl_shortcut_controller_add_command_action (DzlShortcutController *self,
                                             const gchar           *command_id,
                                             const gchar           *default_accel,
+                                            DzlShortcutPhase       phase,
                                             const gchar           *action)
 {
   DzlShortcutClosureChain *chain;
@@ -1014,14 +1033,14 @@ dzl_shortcut_controller_add_command_action (DzlShortcutController *self,
   g_return_if_fail (command_id != NULL);
 
   chain = dzl_shortcut_closure_chain_append_action_string (NULL, action);
-
-  dzl_shortcut_controller_add_command (self, command_id, default_accel, chain);
+  dzl_shortcut_controller_add_command (self, command_id, default_accel, phase, chain);
 }
 
 void
 dzl_shortcut_controller_add_command_callback (DzlShortcutController *self,
                                               const gchar           *command_id,
                                               const gchar           *default_accel,
+                                              DzlShortcutPhase       phase,
                                               GtkCallback            callback,
                                               gpointer               callback_data,
                                               GDestroyNotify         callback_data_destroy)
@@ -1036,13 +1055,14 @@ dzl_shortcut_controller_add_command_callback (DzlShortcutController *self,
                                                       callback_data,
                                                       callback_data_destroy);
 
-  dzl_shortcut_controller_add_command (self, command_id, default_accel, chain);
+  dzl_shortcut_controller_add_command (self, command_id, default_accel, phase, chain);
 }
 
 void
 dzl_shortcut_controller_add_command_signal (DzlShortcutController *self,
                                             const gchar           *command_id,
                                             const gchar           *default_accel,
+                                            DzlShortcutPhase       phase,
                                             const gchar           *signal_name,
                                             guint                  n_args,
                                             ...)
@@ -1057,7 +1077,7 @@ dzl_shortcut_controller_add_command_signal (DzlShortcutController *self,
   chain = dzl_shortcut_closure_chain_append_signal (NULL, signal_name, n_args, args);
   va_end (args);
 
-  dzl_shortcut_controller_add_command (self, command_id, default_accel, chain);
+  dzl_shortcut_controller_add_command (self, command_id, default_accel, phase, chain);
 }
 
 DzlShortcutChord *
diff --git a/src/shortcuts/dzl-shortcut-controller.h b/src/shortcuts/dzl-shortcut-controller.h
index 244284e..0eb2247 100644
--- a/src/shortcuts/dzl-shortcut-controller.h
+++ b/src/shortcuts/dzl-shortcut-controller.h
@@ -48,16 +48,19 @@ const DzlShortcutChord *dzl_shortcut_controller_get_current_chord     (DzlShortc
 void                    dzl_shortcut_controller_add_command_action    (DzlShortcutController *self,
                                                                        const gchar           *command_id,
                                                                        const gchar           *default_accel,
+                                                                       DzlShortcutPhase       phase,
                                                                        const gchar           *action);
 void                    dzl_shortcut_controller_add_command_callback  (DzlShortcutController *self,
                                                                        const gchar           *command_id,
                                                                        const gchar           *default_accel,
+                                                                       DzlShortcutPhase       phase,
                                                                        GtkCallback            callback,
                                                                        gpointer               callback_data,
                                                                        GDestroyNotify         
callback_data_destroy);
 void                    dzl_shortcut_controller_add_command_signal    (DzlShortcutController *self,
                                                                        const gchar           *command_id,
                                                                        const gchar           *default_accel,
+                                                                       DzlShortcutPhase       phase,
                                                                        const gchar           *signal_name,
                                                                        guint                  n_args,
                                                                        ...);
diff --git a/src/shortcuts/dzl-shortcut-manager.c b/src/shortcuts/dzl-shortcut-manager.c
index 5807f40..31259be 100644
--- a/src/shortcuts/dzl-shortcut-manager.c
+++ b/src/shortcuts/dzl-shortcut-manager.c
@@ -1399,7 +1399,8 @@ dzl_shortcut_manager_add_shortcut_entries (DzlShortcutManager     *self,
 
       if (entry->default_accel != NULL)
         dzl_shortcut_theme_set_accel_for_command (priv->internal_theme,
-                                                  entry->command, entry->default_accel);
+                                                  entry->command,
+                                                  entry->default_accel);
 
       dzl_shortcut_manager_add_command (self,
                                         entry->command,
diff --git a/src/shortcuts/dzl-shortcut-private.h b/src/shortcuts/dzl-shortcut-private.h
index cbd40e9..c1e1bf9 100644
--- a/src/shortcuts/dzl-shortcut-private.h
+++ b/src/shortcuts/dzl-shortcut-private.h
@@ -76,6 +76,7 @@ struct _DzlShortcutClosureChain
 
   DzlShortcutClosureType type : 3;
   guint executing : 1;
+  DzlShortcutPhase phase : 2;
 
   union {
     struct {
diff --git a/tests/test-shortcut-theme.c b/tests/test-shortcut-theme.c
index 6b930bc..ca78880 100644
--- a/tests/test-shortcut-theme.c
+++ b/tests/test-shortcut-theme.c
@@ -86,7 +86,7 @@ test_shortcut_theme_manager (void)
   gtk_widget_show_all (window);
   controller = dzl_shortcut_controller_find (label);
   g_assert (DZL_IS_SHORTCUT_CONTROLLER (controller));
-  dzl_shortcut_controller_add_command_callback (controller, "useless.command.here", "<Control>a", 
key_callback, &did_cb, NULL);
+  dzl_shortcut_controller_add_command_callback (controller, "useless.command.here", "<Control>a", 0, 
key_callback, &did_cb, NULL);
   event = dzl_gdk_synthesize_event_keyval (gtk_widget_get_window (label), GDK_KEY_a);
   event->state |= GDK_CONTROL_MASK;
   r = dzl_shortcut_manager_handle_event (NULL, event, window);
diff --git a/tests/test-shortcuts.c b/tests/test-shortcuts.c
index 851c2a2..71ce8ba 100644
--- a/tests/test-shortcuts.c
+++ b/tests/test-shortcuts.c
@@ -15,8 +15,8 @@ typedef struct
 } App;
 
 static const DzlShortcutEntry entries[] = {
-  { "a.b.c.a", "<Control>l", "Editor", "Navigation", "Move to next error" },
-  { "a.b.c.b", "<Control>k", "Editor", "Navigation", "Move to previous error" },
+  { "a.b.c.a", 0, "<Control>l", "Editor", "Navigation", "Move to next error" },
+  { "a.b.c.b", 0, "<Control>k", "Editor", "Navigation", "Move to previous error" },
 };
 
 static void
@@ -103,7 +103,7 @@ main (gint argc,
                              "title", "Shortcuts Test",
                              NULL);
   app.root_controller = dzl_shortcut_controller_new (GTK_WIDGET (app.window));
-  dzl_shortcut_controller_add_command_callback (app.root_controller, "a.b.c.a", NULL, a_b_c_a, NULL, NULL);
+  dzl_shortcut_controller_add_command_callback (app.root_controller, "a.b.c.a", NULL, 0, a_b_c_a, NULL, 
NULL);
 
   g_signal_connect (app.root_controller,
                     "notify::current-chord",
@@ -138,11 +138,13 @@ main (gint argc,
   dzl_shortcut_controller_add_command_signal (app.search_controller,
                                               "com.example.foo.search",
                                               "<ctrl>y|<ctrl>y",
+                                              DZL_SHORTCUT_PHASE_CAPTURE,
                                               "grab-focus",
                                               0);
   dzl_shortcut_controller_add_command_callback (app.search_controller,
                                                 "com.example.foo.test",
                                                 "<ctrl>x|<ctrl>r",
+                                                DZL_SHORTCUT_PHASE_CAPTURE,
                                                 test_callback, NULL, NULL);
 
   app.shortcuts = g_object_new (GTK_TYPE_BUTTON,


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