[gtk/ebassi/activate-signal: 1/6] Add wrappers for setting the WidgetClass.activate_signal field




commit b3e03fa6f0e91ea088c47b7d4f0571dff847a3e1
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Fri Dec 4 17:01:23 2020 +0000

    Add wrappers for setting the WidgetClass.activate_signal field
    
    Setting a field on a class structure is not always an easy task from
    languages other than C. While bindings can provide access to the class
    pointer, twiddling the fields in the class structure can be awkward.
    Additionally, signal ids are not always readily available.
    
    We can paper over the direct access to the class structure, as well as
    the "signal name to id" mapping with a simple couple of setter
    functions.

 docs/reference/gtk/gtk4-sections.txt |  2 ++
 gtk/gtkwidget.c                      | 70 ++++++++++++++++++++++++++++++++++--
 gtk/gtkwidget.h                      |  7 ++++
 3 files changed, 77 insertions(+), 2 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 77316a4fb6..66eae4da6a 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -4366,6 +4366,8 @@ gtk_widget_class_add_binding_signal
 gtk_widget_class_add_binding_action
 gtk_widget_class_set_layout_manager_type
 gtk_widget_class_get_layout_manager_type
+gtk_widget_class_set_activate_signal
+gtk_widget_class_set_activate_signal_from_name
 gtk_widget_activate
 gtk_widget_is_focus
 gtk_widget_grab_focus
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index ab9de00cd2..1ae404c425 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -4296,11 +4296,22 @@ gtk_widget_mnemonic_activate (GtkWidget *widget,
   return handled;
 }
 
+static gboolean
+gtk_widget_can_activate (GtkWidget *self)
+{
+  GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS (self);
+
+  if (widget_class->activate_signal != 0)
+    return TRUE;
+
+  return FALSE;
+}
+
 static gboolean
 gtk_widget_real_mnemonic_activate (GtkWidget *widget,
                                    gboolean   group_cycling)
 {
-  if (!group_cycling && GTK_WIDGET_GET_CLASS (widget)->activate_signal)
+  if (!group_cycling && gtk_widget_can_activate (widget))
     gtk_widget_activate (widget);
   else if (gtk_widget_get_can_focus (widget))
     return gtk_widget_grab_focus (widget);
@@ -4562,6 +4573,61 @@ gtk_widget_event (GtkWidget *widget,
   return return_val;
 }
 
+/**
+ * gtk_widget_class_set_activate_signal:
+ * @widget_class: a #GtkWidgetClass
+ * @signal_id: the id for the activate signal
+ *
+ * Sets the #GtkWidgetClass.activate_signal field with the
+ * given @signal_id; the signal will be emitted when calling
+ * gtk_widget_activate().
+ *
+ * The @signal_id must have been registered with g_signal_new()
+ * or g_signal_newv() before calling this function.
+ */
+void
+gtk_widget_class_set_activate_signal (GtkWidgetClass *widget_class,
+                                      guint           signal_id)
+{
+  g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
+  g_return_if_fail (signal_id != 0);
+
+  widget_class->activate_signal = signal_id;
+}
+
+/**
+ * gtk_widget_class_set_activate_signal_from_name:
+ * @widget_class: a #GtkWidgetClass
+ * @signal_name: the name of the activate signal of @widget_type
+ *
+ * Sets the #GtkWidgetClass.activate_signal field with the signal id for
+ * the given @signal_name; the signal will be emitted when calling
+ * gtk_widget_activate().
+ *
+ * The @signal_name of @widget_type must have been registered with
+ * g_signal_new() or g_signal_newv() before calling this function.
+ */
+void
+gtk_widget_class_set_activate_signal_from_name (GtkWidgetClass *widget_class,
+                                                const char     *signal_name)
+{
+  guint signal_id;
+
+  g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
+  g_return_if_fail (signal_name != NULL);
+
+  signal_id = g_signal_lookup (signal_name, G_TYPE_FROM_CLASS (widget_class));
+  if (signal_id == 0)
+    {
+      g_critical ("Widget type “%s” does not have a “%s” signal",
+                  G_OBJECT_CLASS_NAME (widget_class),
+                  signal_name);
+      return;
+    }
+
+  widget_class->activate_signal = signal_id;
+}
+
 /**
  * gtk_widget_activate:
  * @widget: a #GtkWidget that’s activatable
@@ -4578,7 +4644,7 @@ gtk_widget_activate (GtkWidget *widget)
 {
   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
 
-  if (GTK_WIDGET_GET_CLASS (widget)->activate_signal)
+  if (gtk_widget_can_activate (widget))
     {
       /* FIXME: we should eventually check the signals signature here */
       g_signal_emit (widget, GTK_WIDGET_GET_CLASS (widget)->activate_signal, 0);
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 61379b558e..8aa2403ac9 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -364,6 +364,13 @@ GDK_AVAILABLE_IN_ALL
 void       gtk_widget_class_add_shortcut  (GtkWidgetClass      *widget_class,
                                            GtkShortcut         *shortcut);
 
+GDK_AVAILABLE_IN_ALL
+void       gtk_widget_class_set_activate_signal                 (GtkWidgetClass *widget_class,
+                                                                 guint           signal_id);
+GDK_AVAILABLE_IN_ALL
+void       gtk_widget_class_set_activate_signal_from_name       (GtkWidgetClass *widget_class,
+                                                                 const char     *signal_name);
+
 GDK_AVAILABLE_IN_ALL
 gboolean   gtk_widget_mnemonic_activate   (GtkWidget           *widget,
                                            gboolean             group_cycling);


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