[gtk/wip/matthiasc/shortcut-4: 19/139] trigger: Add an alternative trigger
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/matthiasc/shortcut-4: 19/139] trigger: Add an alternative trigger
- Date: Thu, 26 Mar 2020 02:38:24 +0000 (UTC)
commit 81fa63260e0c25343a8dd2fee5ba32b5d4a46516
Author: Benjamin Otte <otte redhat com>
Date: Sun Aug 5 04:10:11 2018 +0200
trigger: Add an alternative trigger
And use it.
I just added it to GtkWidget just to show that I can.
The real reason I want it is for gamepad/joystick triggers
in games, so that it becomes possible to select 2 different
triggers (gamepad and keyboard) for the same shortcut.
gtk/gtkshortcuttrigger.c | 168 ++++++++++++++++++++++++++++++++++++++++-------
gtk/gtkshortcuttrigger.h | 15 ++++-
gtk/gtkwindow.c | 24 ++++---
3 files changed, 172 insertions(+), 35 deletions(-)
---
diff --git a/gtk/gtkshortcuttrigger.c b/gtk/gtkshortcuttrigger.c
index 6a0ad9d547..5044e7a164 100644
--- a/gtk/gtkshortcuttrigger.c
+++ b/gtk/gtkshortcuttrigger.c
@@ -65,10 +65,6 @@ struct _GtkShortcutTriggerClass
GString *string);
};
-static GtkShortcutTrigger * gtk_shortcut_trigger_new (const GtkShortcutTriggerClass
*trigger_class,
- gsize
extra_size);
-
-
G_DEFINE_BOXED_TYPE (GtkShortcutTrigger, gtk_shortcut_trigger,
gtk_shortcut_trigger_ref,
gtk_shortcut_trigger_unref)
@@ -87,15 +83,14 @@ gtk_shortcut_trigger_finalize (GtkShortcutTrigger *self)
*
* Returns: (transfer full): the newly created #GtkShortcutTrigger
*/
-GtkShortcutTrigger *
-gtk_shortcut_trigger_new (const GtkShortcutTriggerClass *trigger_class,
- gsize extra_size)
+static GtkShortcutTrigger *
+gtk_shortcut_trigger_new (const GtkShortcutTriggerClass *trigger_class)
{
GtkShortcutTrigger *self;
g_return_val_if_fail (trigger_class != NULL, NULL);
- self = g_malloc0 (trigger_class->struct_size + extra_size);
+ self = g_malloc0 (trigger_class->struct_size);
g_atomic_ref_count_init (&self->ref_count);
self->trigger_class = trigger_class;
@@ -232,20 +227,20 @@ struct _GtkNeverTrigger
};
static void
-gsk_never_trigger_finalize (GtkShortcutTrigger *trigger)
+gtk_never_trigger_finalize (GtkShortcutTrigger *trigger)
{
g_assert_not_reached ();
}
static gboolean
-gsk_never_trigger_trigger (GtkShortcutTrigger *trigger,
+gtk_never_trigger_trigger (GtkShortcutTrigger *trigger,
GdkEvent *event)
{
return FALSE;
}
static void
-gsk_never_trigger_print (GtkShortcutTrigger *trigger,
+gtk_never_trigger_print (GtkShortcutTrigger *trigger,
GString *string)
{
g_string_append (string, "<never>");
@@ -255,15 +250,15 @@ static const GtkShortcutTriggerClass GTK_NEVER_TRIGGER_CLASS = {
GTK_SHORTCUT_TRIGGER_NEVER,
sizeof (GtkNeverTrigger),
"GtkNeverTrigger",
- gsk_never_trigger_finalize,
- gsk_never_trigger_trigger,
- gsk_never_trigger_print
+ gtk_never_trigger_finalize,
+ gtk_never_trigger_trigger,
+ gtk_never_trigger_print
};
static GtkNeverTrigger never = { { >K_NEVER_TRIGGER_CLASS, 1 } };
/**
- * gsk_never_trigger_get:
+ * gtk_never_trigger_get:
*
* Gets the never trigger. This is a singleton for a trigger
* that never triggers. Use this trigger instead of %NULL
@@ -290,12 +285,12 @@ struct _GtkKeyvalTrigger
};
static void
-gsk_keyval_trigger_finalize (GtkShortcutTrigger *trigger)
+gtk_keyval_trigger_finalize (GtkShortcutTrigger *trigger)
{
}
static gboolean
-gsk_keyval_trigger_trigger (GtkShortcutTrigger *trigger,
+gtk_keyval_trigger_trigger (GtkShortcutTrigger *trigger,
GdkEvent *event)
{
GtkKeyvalTrigger *self = (GtkKeyvalTrigger *) trigger;
@@ -318,7 +313,7 @@ gsk_keyval_trigger_trigger (GtkShortcutTrigger *trigger,
}
static void
-gsk_keyval_trigger_print (GtkShortcutTrigger *trigger,
+gtk_keyval_trigger_print (GtkShortcutTrigger *trigger,
GString *string)
{
GtkKeyvalTrigger *self = (GtkKeyvalTrigger *) trigger;
@@ -333,13 +328,13 @@ static const GtkShortcutTriggerClass GTK_KEYVAL_TRIGGER_CLASS = {
GTK_SHORTCUT_TRIGGER_KEYVAL,
sizeof (GtkKeyvalTrigger),
"GtkKeyvalTrigger",
- gsk_keyval_trigger_finalize,
- gsk_keyval_trigger_trigger,
- gsk_keyval_trigger_print
+ gtk_keyval_trigger_finalize,
+ gtk_keyval_trigger_trigger,
+ gtk_keyval_trigger_print
};
/**
- * gsk_keyval_trigger_new:
+ * gtk_keyval_trigger_new:
* @keyval: The keyval to trigger for
* @modifiers: the modifiers that need to be present
*
@@ -354,7 +349,7 @@ gtk_keyval_trigger_new (guint keyval,
{
GtkKeyvalTrigger *self;
- self = (GtkKeyvalTrigger *) gtk_shortcut_trigger_new (>K_KEYVAL_TRIGGER_CLASS, 0);
+ self = (GtkKeyvalTrigger *) gtk_shortcut_trigger_new (>K_KEYVAL_TRIGGER_CLASS);
/* We store keyvals as lower key */
if (keyval == GDK_KEY_ISO_Left_Tab)
@@ -403,3 +398,130 @@ gtk_keyval_trigger_get_keyval (GtkShortcutTrigger *self)
return trigger->keyval;
}
+
+/*** GTK_ALTERNATIVE_TRIGGER ***/
+
+typedef struct _GtkAlternativeTrigger GtkAlternativeTrigger;
+
+struct _GtkAlternativeTrigger
+{
+ GtkShortcutTrigger trigger;
+
+ GtkShortcutTrigger *first;
+ GtkShortcutTrigger *second;
+};
+
+static void
+gtk_alternative_trigger_finalize (GtkShortcutTrigger *trigger)
+{
+ GtkAlternativeTrigger *self = (GtkAlternativeTrigger *) trigger;
+
+ gtk_shortcut_trigger_unref (self->first);
+ gtk_shortcut_trigger_unref (self->second);
+}
+
+static gboolean
+gtk_alternative_trigger_trigger (GtkShortcutTrigger *trigger,
+ GdkEvent *event)
+{
+ GtkAlternativeTrigger *self = (GtkAlternativeTrigger *) trigger;
+
+ if (gtk_shortcut_trigger_trigger (self->first, event))
+ return TRUE;
+
+ if (gtk_shortcut_trigger_trigger (self->second, event))
+ return TRUE;
+
+ return FALSE;
+}
+
+static void
+gtk_alternative_trigger_print (GtkShortcutTrigger *trigger,
+ GString *string)
+
+{
+ GtkAlternativeTrigger *self = (GtkAlternativeTrigger *) trigger;
+
+ gtk_shortcut_trigger_print (self->first, string);
+ g_string_append (string, ", ");
+ gtk_shortcut_trigger_print (self->second, string);
+}
+
+static const GtkShortcutTriggerClass GTK_ALTERNATIVE_TRIGGER_CLASS = {
+ GTK_SHORTCUT_TRIGGER_ALTERNATIVE,
+ sizeof (GtkAlternativeTrigger),
+ "GtkAlternativeTrigger",
+ gtk_alternative_trigger_finalize,
+ gtk_alternative_trigger_trigger,
+ gtk_alternative_trigger_print
+};
+
+/**
+ * gtk_alternative_trigger_new:
+ * @first: (transfer full): The first trigger that may trigger
+ * @second: (transfer full): The second trigger that may trigger
+ *
+ * Creates a #GtkShortcutTrigger that will trigger whenever
+ * either of the two given triggers gets triggered.
+ *
+ * Note that nesting is allowed, so if you want more than two
+ * alternative, create a new alternative trigger for each option.
+ *
+ * Returns: a new #GtkShortcutTrigger
+ */
+GtkShortcutTrigger *
+gtk_alternative_trigger_new (GtkShortcutTrigger *first,
+ GtkShortcutTrigger *second)
+{
+ GtkAlternativeTrigger *self;
+
+ g_return_val_if_fail (GTK_IS_SHORTCUT_TRIGGER (first), NULL);
+ g_return_val_if_fail (GTK_IS_SHORTCUT_TRIGGER (second), NULL);
+
+ self = (GtkAlternativeTrigger *) gtk_shortcut_trigger_new (>K_ALTERNATIVE_TRIGGER_CLASS);
+
+ self->first = first;
+ self->second = second;
+
+ return &self->trigger;
+}
+
+/**
+ * gtk_alternative_trigger_get_first:
+ * @self: an alternative #GtkShortcutTrigger
+ *
+ * Gets the first of the two alternative triggers that may
+ * trigger @self. gtk_alternative_trigger_get_second() will
+ * return the other one.
+ *
+ * Returns: (transfer none): the first alternative trigger
+ **/
+GtkShortcutTrigger *
+gtk_alternative_trigger_get_first (GtkShortcutTrigger *self)
+{
+ GtkAlternativeTrigger *trigger = (GtkAlternativeTrigger *) self;
+
+ g_return_val_if_fail (GTK_IS_SHORTCUT_TRIGGER_TYPE (self, GTK_SHORTCUT_TRIGGER_ALTERNATIVE), 0);
+
+ return trigger->first;
+}
+
+/**
+ * gtk_alternative_trigger_get_second:
+ * @self: an alternative #GtkShortcutTrigger
+ *
+ * Gets the second of the two alternative triggers that may
+ * trigger @self. gtk_alternative_trigger_get_first() will
+ * return the other one.
+ *
+ * Returns: (transfer none): the second alternative trigger
+ **/
+GtkShortcutTrigger *
+gtk_alternative_trigger_get_second (GtkShortcutTrigger *self)
+{
+ GtkAlternativeTrigger *trigger = (GtkAlternativeTrigger *) self;
+
+ g_return_val_if_fail (GTK_IS_SHORTCUT_TRIGGER_TYPE (self, GTK_SHORTCUT_TRIGGER_ALTERNATIVE), 0);
+
+ return trigger->second;
+}
diff --git a/gtk/gtkshortcuttrigger.h b/gtk/gtkshortcuttrigger.h
index 582a389f45..d37fbcc222 100644
--- a/gtk/gtkshortcuttrigger.h
+++ b/gtk/gtkshortcuttrigger.h
@@ -35,14 +35,17 @@ G_BEGIN_DECLS
/**
* GtkShortcutTriggerType:
* @GTK_SHORTCUT_TRIGGER_NEVER: Never ever trigger
- * @GTK_SHORTCUT_TRIGGER_KEYVAL: Trigger if a key even with matching
+ * @GTK_SHORTCUT_TRIGGER_KEYVAL: Trigger if a key event with matching
* modifiers and keyval is received.
+ * @GTK_SHORTCUT_TRIGGER_ALTERNAITVE: Trigger if either if two
+ * alternatives triggers
*
* The type of a trigger determines what the trigger triggers on.
**/
typedef enum {
GTK_SHORTCUT_TRIGGER_NEVER,
- GTK_SHORTCUT_TRIGGER_KEYVAL
+ GTK_SHORTCUT_TRIGGER_KEYVAL,
+ GTK_SHORTCUT_TRIGGER_ALTERNATIVE
} GtkShortcutTriggerType;
GDK_AVAILABLE_IN_ALL
@@ -77,6 +80,14 @@ GdkModifierType gtk_keyval_trigger_get_modifiers (GtkShortcutTrig
GDK_AVAILABLE_IN_ALL
guint gtk_keyval_trigger_get_keyval (GtkShortcutTrigger *self);
+GDK_AVAILABLE_IN_ALL
+GtkShortcutTrigger * gtk_alternative_trigger_new (GtkShortcutTrigger *one,
+ GtkShortcutTrigger *two);
+GDK_AVAILABLE_IN_ALL
+GtkShortcutTrigger * gtk_alternative_trigger_get_first (GtkShortcutTrigger *self);
+GDK_AVAILABLE_IN_ALL
+GtkShortcutTrigger * gtk_alternative_trigger_get_second (GtkShortcutTrigger *self);
+
G_END_DECLS
#endif /* __GTK_SHORTCUT_TRIGGER_H__ */
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 40ac4591df..95764e53f0 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -62,6 +62,8 @@
#include "gtkroot.h"
#include "gtknative.h"
#include "gtksettings.h"
+#include "gtkshortcut.h"
+#include "gtkshortcuttrigger.h"
#include "gtksnapshot.h"
#include "gtkstylecontextprivate.h"
#include "gtktypebuiltins.h"
@@ -556,16 +558,18 @@ add_tab_bindings (GtkWidgetClass *widget_class,
GdkModifierType modifiers,
GtkDirectionType direction)
{
- gtk_widget_class_add_binding_signal (widget_class,
- GDK_KEY_Tab, modifiers,
- "move-focus",
- "(i)",
- direction);
- gtk_widget_class_add_binding_signal (widget_class,
- GDK_KEY_KP_Tab, modifiers,
- "move-focus",
- "(i)",
- direction);
+ GtkShortcut *shortcut;
+
+ shortcut = gtk_shortcut_new ();
+ gtk_shortcut_set_trigger (shortcut,
+ gtk_alternative_trigger_new (gtk_keyval_trigger_new (GDK_KEY_Tab, modifiers),
+ gtk_keyval_trigger_new (GDK_KEY_KP_Tab,
modifiers)));
+ gtk_shortcut_set_signal (shortcut, "move-focus");
+ gtk_shortcut_set_arguments (shortcut, g_variant_new_tuple ((GVariant*[1]) { g_variant_new_int32
(direction) }, 1));
+
+ gtk_widget_class_add_shortcut (widget_class, shortcut);
+
+ g_object_unref (shortcut);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]