diff options
| author | Benjamin Otte <otte@redhat.com> | 2019-10-15 05:50:52 +0200 |
|---|---|---|
| committer | Benjamin Otte <otte@redhat.com> | 2019-10-15 07:17:30 +0200 |
| commit | a1a70a1130a45a00767bddb000d550eca23ec3c4 (patch) | |
| tree | b5ad4297a15cec252704cca2cd840ad8abe5f73c /gtk | |
| parent | 19304c1d2c8df4ca1e8ba11337ece80553911761 (diff) | |
| download | gtk+-a1a70a1130a45a00767bddb000d550eca23ec3c4.tar.gz | |
bindings: Add gtk_binding_entry_add_callback()
This allows bindings that have no public API.
Diffstat (limited to 'gtk')
| -rw-r--r-- | gtk/gtkbindings.c | 133 | ||||
| -rw-r--r-- | gtk/gtkbindings.h | 9 |
2 files changed, 108 insertions, 34 deletions
diff --git a/gtk/gtkbindings.c b/gtk/gtkbindings.c index 59c1815772..49acdc661d 100644 --- a/gtk/gtkbindings.c +++ b/gtk/gtkbindings.c @@ -141,7 +141,8 @@ struct _GtkBindingArg typedef enum { GTK_BINDING_SIGNAL, - GTK_BINDING_ACTION + GTK_BINDING_ACTION, + GTK_BINDING_CALLBACK } GtkBindingActionType; /** @@ -166,6 +167,11 @@ struct _GtkBindingSignal GtkBindingArg *args; }; GVariant *variant; + struct { + GtkCallback callback; + gpointer user_data; + GDestroyNotify user_destroy; + } callback; }; }; @@ -212,6 +218,23 @@ binding_signal_new_action (const gchar *signal_name, return signal; } +static GtkBindingSignal * +binding_signal_new_callback (GtkCallback callback, + gpointer user_data, + GDestroyNotify user_destroy) +{ + GtkBindingSignal *signal; + + signal = g_slice_new0 (GtkBindingSignal); + signal->next = NULL; + signal->action_type = GTK_BINDING_CALLBACK; + signal->callback.callback = callback; + signal->callback.user_data = user_data; + signal->callback.user_destroy = user_destroy; + + return signal; +} + static void binding_signal_free (GtkBindingSignal *sig) { @@ -233,6 +256,12 @@ binding_signal_free (GtkBindingSignal *sig) g_slice_free (GtkBindingSignal, sig); break; + case GTK_BINDING_CALLBACK: + if (sig->callback.user_destroy) + sig->callback.user_destroy (sig->callback.user_data); + g_slice_free (GtkBindingSignal, sig); + break; + default: g_assert_not_reached (); break; @@ -695,6 +724,23 @@ binding_signal_activate_action (GtkBindingSignal *sig, } static gboolean +binding_signal_activate_callback (GtkBindingSignal *sig, + GObject *object) +{ + if (!GTK_IS_WIDGET (object)) + { + g_warning ("gtk_binding_entry_activate(): " + "callbacks must be run on GtkWidget subtypes, %s is not supported", + G_OBJECT_TYPE_NAME (object)); + return FALSE; + } + + sig->callback.callback (GTK_WIDGET (object), sig->callback.user_data); + + return TRUE; +} + +static gboolean gtk_binding_entry_activate (GtkBindingEntry *entry, GObject *object) { @@ -719,6 +765,10 @@ gtk_binding_entry_activate (GtkBindingEntry *entry, handled = binding_signal_activate_action (sig, object); break; + case GTK_BINDING_CALLBACK: + handled = binding_signal_activate_callback (sig, object); + break; + default: g_assert_not_reached (); break; @@ -938,6 +988,30 @@ gtk_binding_entry_remove (GtkBindingSet *binding_set, binding_entry_destroy (entry); } +static void +gtk_binding_entry_add_binding_signal (GtkBindingSet *binding_set, + guint keyval, + GdkModifierType modifiers, + GtkBindingSignal *signal) +{ + GtkBindingEntry *entry; + GtkBindingSignal **signal_p; + + keyval = gdk_keyval_to_lower (keyval); + modifiers = modifiers & BINDING_MOD_MASK (); + + entry = binding_ht_lookup_entry (binding_set, keyval, modifiers); + if (!entry) + { + gtk_binding_entry_clear_internal (binding_set, keyval, modifiers); + entry = binding_ht_lookup_entry (binding_set, keyval, modifiers); + } + signal_p = &entry->signals; + while (*signal_p) + signal_p = &(*signal_p)->next; + *signal_p = signal; +} + /* * gtk_binding_entry_add_signall: * @binding_set: a #GtkBindingSet to add a signal to @@ -957,8 +1031,7 @@ gtk_binding_entry_add_signall (GtkBindingSet *binding_set, const gchar *signal_name, GSList *binding_args) { - GtkBindingEntry *entry; - GtkBindingSignal *signal, **signal_p; + GtkBindingSignal *signal; GSList *slist; guint n = 0; GtkBindingArg *arg; @@ -966,9 +1039,6 @@ gtk_binding_entry_add_signall (GtkBindingSet *binding_set, g_return_if_fail (binding_set != NULL); g_return_if_fail (signal_name != NULL); - keyval = gdk_keyval_to_lower (keyval); - modifiers = modifiers & BINDING_MOD_MASK (); - signal = binding_signal_new_signal (signal_name, g_slist_length (binding_args)); arg = signal->args; @@ -1013,16 +1083,7 @@ gtk_binding_entry_add_signall (GtkBindingSet *binding_set, n++; } - entry = binding_ht_lookup_entry (binding_set, keyval, modifiers); - if (!entry) - { - gtk_binding_entry_clear_internal (binding_set, keyval, modifiers); - entry = binding_ht_lookup_entry (binding_set, keyval, modifiers); - } - signal_p = &entry->signals; - while (*signal_p) - signal_p = &(*signal_p)->next; - *signal_p = signal; + gtk_binding_entry_add_binding_signal (binding_set, keyval, modifiers, signal); } /** @@ -1159,27 +1220,13 @@ gtk_binding_entry_add_action_variant (GtkBindingSet *binding_set, const gchar *action_name, GVariant *args) { - GtkBindingEntry *entry; - GtkBindingSignal *signal, **signal_p; - g_return_if_fail (binding_set != NULL); g_return_if_fail (action_name != NULL); - keyval = gdk_keyval_to_lower (keyval); - modifiers = modifiers & BINDING_MOD_MASK (); - - signal = binding_signal_new_action (action_name, args); - - entry = binding_ht_lookup_entry (binding_set, keyval, modifiers); - if (!entry) - { - gtk_binding_entry_clear_internal (binding_set, keyval, modifiers); - entry = binding_ht_lookup_entry (binding_set, keyval, modifiers); - } - signal_p = &entry->signals; - while (*signal_p) - signal_p = &(*signal_p)->next; - *signal_p = signal; + gtk_binding_entry_add_binding_signal (binding_set, + keyval, + modifiers, + binding_signal_new_action (action_name, args)); } /** @@ -1226,6 +1273,24 @@ gtk_binding_entry_add_action (GtkBindingSet *binding_set, g_clear_pointer (¶meters, g_variant_unref); } +void +gtk_binding_entry_add_callback (GtkBindingSet *binding_set, + guint keyval, + GdkModifierType modifiers, + GtkCallback callback, + gpointer user_data, + GDestroyNotify user_destroy) +{ + g_return_if_fail (binding_set != NULL); + g_return_if_fail (callback != NULL); + + gtk_binding_entry_add_binding_signal (binding_set, + keyval, + modifiers, + binding_signal_new_callback (callback, user_data, user_destroy)); + +} + static guint gtk_binding_parse_signal (GScanner *scanner, GtkBindingSet *binding_set, diff --git a/gtk/gtkbindings.h b/gtk/gtkbindings.h index 5f2b019006..9d68ce301e 100644 --- a/gtk/gtkbindings.h +++ b/gtk/gtkbindings.h @@ -35,6 +35,7 @@ #include <gdk/gdk.h> #include <gtk/gtkenums.h> +#include <gtk/gtkwidget.h> G_BEGIN_DECLS @@ -92,6 +93,14 @@ void gtk_binding_entry_add_action (GtkBindingSet *binding_set, ...); GDK_AVAILABLE_IN_ALL +void gtk_binding_entry_add_callback(GtkBindingSet *binding_set, + guint keyval, + GdkModifierType modifiers, + GtkCallback callback, + gpointer user_data, + GDestroyNotify user_destroy); + +GDK_AVAILABLE_IN_ALL void gtk_binding_entry_remove (GtkBindingSet *binding_set, guint keyval, GdkModifierType modifiers); |
