[gtksourceview/wip/various-stuff: 2/3] Completion: weak reference to the view



commit b65363196bb2976df7b6085a0f77c27e2c913ffa
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Sun Jan 26 20:30:26 2014 +0100

    Completion: weak reference to the view
    
    There was a reference cycle between the view and completion. Now only
    the view has a strong reference to the completion. It is more logical
    that the view owns the completion, not vice-versa.
    
    This wasn't really a problem as far as the view was added to a
    container. Because when the container is destroyed, it calls
    gtk_widget_destroy() on its children, which calls g_object_run_dispose()
    which breaks the reference cycle.
    
    Anyway, it's better to not rely on gtk_widget_destroy(), and thus avoid
    reference cycles in C code.

 gtksourceview/gtksourcecompletion.c |   26 +++++++++++++++++++-------
 1 files changed, 19 insertions(+), 7 deletions(-)
---
diff --git a/gtksourceview/gtksourcecompletion.c b/gtksourceview/gtksourcecompletion.c
index 4acdf5b..7d3c4cd 100644
--- a/gtksourceview/gtksourcecompletion.c
+++ b/gtksourceview/gtksourcecompletion.c
@@ -1560,7 +1560,14 @@ gtk_source_completion_dispose (GObject *object)
 
        reset_completion (completion);
 
-       g_clear_object (&completion->priv->view);
+       if (completion->priv->view != NULL)
+       {
+               g_object_remove_weak_pointer (G_OBJECT (completion->priv->view),
+                                             (gpointer *)&completion->priv->view);
+
+               completion->priv->view = NULL;
+       }
+
        g_clear_object (&completion->priv->default_info);
        g_clear_object (&completion->priv->model_proposals);
 
@@ -1583,10 +1590,17 @@ gtk_source_completion_dispose (GObject *object)
 }
 
 static void
-connect_view (GtkSourceCompletion *completion)
+connect_view (GtkSourceCompletion *completion,
+             GtkSourceView       *view)
 {
-       GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (completion->priv->view));
-       GtkStyleContext *style_context = gtk_widget_get_style_context (GTK_WIDGET (completion->priv->view));
+       GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+       GtkStyleContext *style_context = gtk_widget_get_style_context (GTK_WIDGET (view));
+
+       g_assert (completion->priv->view == NULL);
+       completion->priv->view = view;
+
+       g_object_add_weak_pointer (G_OBJECT (view),
+                                  (gpointer *)&completion->priv->view);
 
        g_signal_connect_object (completion->priv->view,
                                 "focus-out-event",
@@ -1733,9 +1747,7 @@ gtk_source_completion_set_property (GObject      *object,
        switch (prop_id)
        {
                case PROP_VIEW:
-                       /* On construction only */
-                       completion->priv->view = g_value_dup_object (value);
-                       connect_view (completion);
+                       connect_view (completion, g_value_get_object (value));
                        break;
                case PROP_REMEMBER_INFO_VISIBILITY:
                        completion->priv->remember_info_visibility = g_value_get_boolean (value);


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