bindings: Add gtk_binding_entry_add_callback()
authorBenjamin Otte <otte@redhat.com>
Tue, 15 Oct 2019 03:50:52 +0000 (05:50 +0200)
committerBenjamin Otte <otte@redhat.com>
Tue, 15 Oct 2019 05:17:30 +0000 (07:17 +0200)
This allows bindings that have no public API.

docs/reference/gtk/gtk4-sections.txt
gtk/gtkbindings.c
gtk/gtkbindings.h

index 2ad5b92fccca7408e9928e7753b3bc124bf1b983..faf10c55255e8d3ef9d99e1d4df6d8117e2d7443 100644 (file)
@@ -5249,6 +5249,7 @@ gtk_bindings_activate_event
 gtk_binding_set_activate
 gtk_binding_entry_add_action
 gtk_binding_entry_add_action_variant
+gtk_binding_entry_add_callback
 gtk_binding_entry_add_signal
 gtk_binding_entry_add_signal_from_string
 gtk_binding_entry_skip
index 59c1815772ee2b5564b1b557e515437d241a84d6..49acdc661d53bc967b5cffcb21d98c41a3a0bf10 100644 (file)
@@ -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;
@@ -694,6 +723,23 @@ binding_signal_activate_action (GtkBindingSignal *sig,
   return TRUE;
 }
 
+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 (&parameters, 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,
index 5f2b0190061d5e1701e2310a37be3486740dc8c1..9d68ce301ecd85fec4a71d5c9c05ae10411b9494 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <gdk/gdk.h>
 #include <gtk/gtkenums.h>
+#include <gtk/gtkwidget.h>
 
 G_BEGIN_DECLS
 
@@ -91,6 +92,14 @@ void           gtk_binding_entry_add_action  (GtkBindingSet       *binding_set,
                                               const char          *format_string,
                                               ...);
 
+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,