[gtk/ebassi/finish-template] Add gtk_widget_clear_template()




commit 344335bf08503ce4e3d1365c00fef56ed5ea688b
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Mon May 16 14:10:20 2022 +0100

    Add gtk_widget_clear_template()
    
    The dual of gtk_widget_init_template(), which should be used to clear
    the template data associated with a specific GtkWidget type.

 gtk/gtkwidget.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkwidget.h |  3 +++
 2 files changed, 66 insertions(+)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 3d1a46897d..c1ee47e859 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -10978,6 +10978,69 @@ out:
   g_object_unref (builder);
 }
 
+/**
+ * gtk_widget_clear_template:
+ * @widget: the widget with a template
+ * @widget_type: the type of the widget to finalize the template for
+ *
+ * Clears the template data for the given widget.
+ *
+ * This function is the opposite of [method@Gtk.Widget.init_template], and
+ * it is used to clear all the template data from a widget instance.
+ *
+ * You should call this function inside the `GObjectClass.dispose()`
+ * implementation of any widget that called `gtk_widget_init_template()`.
+ * Typically, you will want to call this function last, right before
+ * chaining up to the parent type's dispose implementation, e.g.
+ *
+ * ```c
+ * static void
+ * some_widget_dispose (GObject *gobject)
+ * {
+ *   SomeWidget *self = SOME_WIDGET (gobject);
+ *
+ *   // Clear the template data for SomeWidget
+ *   gtk_widget_clear_template (GTK_WIDGET (self), SOME_TYPE_WIDGET);
+ *
+ *   G_OBJECT_CLASS (some_widget_parent_class)->dispose (gobject);
+ * }
+ * ```
+ *
+ * Since: 4.8
+ */
+void
+gtk_widget_clear_template (GtkWidget *widget,
+                           GType      widget_type)
+{
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+  g_return_if_fail (g_type_name (widget_type) != NULL);
+
+  GtkWidgetTemplate *template = GTK_WIDGET_GET_CLASS (widget)->priv->template;
+  g_return_if_fail (template != NULL);
+
+  g_clear_object (&template->scope);
+
+  /* Tear down the automatic child data */
+  for (GSList *l = template->children; l != NULL; l = l->next)
+    {
+      AutomaticChildClass *child_class = l->data;
+
+      /* Nullify the field first, to avoid re-entrancy issues */
+      if (child_class->offset != 0)
+        {
+          gpointer field_p;
+
+          field_p = G_STRUCT_MEMBER_P (widget, child_class->offset);
+          (* (gpointer *) field_p) = NULL;
+        }
+
+      /* This will drop the reference on the template children */
+      GHashTable *auto_child_hash = get_auto_child_hash (widget, widget_type, FALSE);
+      if (auto_child_hash != NULL)
+        g_hash_table_remove (auto_child_hash, child_class->name);
+    }
+}
+
 /**
  * gtk_widget_class_set_template:
  * @widget_class: A `GtkWidgetClass`
diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h
index 0788fcdd81..fede1b634e 100644
--- a/gtk/gtkwidget.h
+++ b/gtk/gtkwidget.h
@@ -833,6 +833,9 @@ GDK_AVAILABLE_IN_ALL
 GObject *gtk_widget_get_template_child                  (GtkWidget             *widget,
                                                          GType                  widget_type,
                                                          const char            *name);
+GDK_AVAILABLE_IN_4_8
+void    gtk_widget_clear_template                       (GtkWidget             *widget,
+                                                         GType                  widget_type);
 GDK_AVAILABLE_IN_ALL
 void    gtk_widget_class_set_template                   (GtkWidgetClass        *widget_class,
                                                          GBytes                *template_bytes);


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