[libdazzle] shortcuts: add phase tracking to controller commands
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libdazzle] shortcuts: add phase tracking to controller commands
- Date: Wed, 19 Jul 2017 01:13:08 +0000 (UTC)
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]