[gnome-builder/gnome-builder-3-20] editor: try extra hard to destroy source views



commit fb916fe78fec72bcafde6695060aced8cf40a3ee
Author: Christian Hergert <chergert redhat com>
Date:   Wed May 11 17:33:14 2016 +0300

    editor: try extra hard to destroy source views
    
    There are lots of chances that we could be holding onto source views
    longer than we need due to async operations. We want to make sure these
    get destroyed as soon as possible, so forcefully call destroy down the
    chain to ensure destruction.

 libide/editor/ide-editor-frame.c  |   21 +++++++++++++++++++
 libide/editor/ide-editor-view.c   |   23 ++++++++++++++++++++-
 libide/ide-buffer.c               |    6 ++++-
 libide/ide-layout-stack-actions.c |   39 +++++++++++++++++++++++-------------
 libide/ide-source-view.c          |    6 ++++-
 5 files changed, 78 insertions(+), 17 deletions(-)
---
diff --git a/libide/editor/ide-editor-frame.c b/libide/editor/ide-editor-frame.c
index c423248..cdf3085 100644
--- a/libide/editor/ide-editor-frame.c
+++ b/libide/editor/ide-editor-frame.c
@@ -808,6 +808,26 @@ ide_editor_frame_constructed (GObject *object)
 }
 
 static void
+ide_editor_frame_destroy (GtkWidget *widget)
+{
+  IdeEditorFrame *self = (IdeEditorFrame *)widget;
+
+  IDE_ENTRY;
+
+  g_assert (IDE_IS_EDITOR_FRAME (self));
+
+  if (self->source_view)
+    {
+      gtk_widget_destroy (GTK_WIDGET (self->source_view));
+      self->source_view = NULL;
+    }
+
+  GTK_WIDGET_CLASS (ide_editor_frame_parent_class)->destroy (widget);
+
+  IDE_EXIT;
+}
+
+static void
 ide_editor_frame_dispose (GObject *object)
 {
   IdeEditorFrame *self = (IdeEditorFrame *)object;
@@ -904,6 +924,7 @@ ide_editor_frame_class_init (IdeEditorFrameClass *klass)
   object_class->get_property = ide_editor_frame_get_property;
   object_class->set_property = ide_editor_frame_set_property;
 
+  widget_class->destroy = ide_editor_frame_destroy;
   widget_class->grab_focus = ide_editor_frame_grab_focus;
 
   properties [PROP_AUTO_HIDE_MAP] =
diff --git a/libide/editor/ide-editor-view.c b/libide/editor/ide-editor-view.c
index babb98e..96ea8d2 100644
--- a/libide/editor/ide-editor-view.c
+++ b/libide/editor/ide-editor-view.c
@@ -813,11 +813,32 @@ ide_editor_view_destroy (GtkWidget *widget)
 {
   IdeEditorView *self = (IdeEditorView *)widget;
 
+  IDE_ENTRY;
+
   ide_editor_view_unload_addins (self);
 
-  GTK_WIDGET_CLASS (ide_editor_view_parent_class)->destroy (widget);
+  /*
+   * We want to make extra sure these widgets get destroyed, so manually
+   * destroy them here before doing any other work.
+   */
+
+  if (self->frame1)
+    {
+      gtk_widget_destroy (GTK_WIDGET (self->frame1));
+      self->frame1 = NULL;
+    }
+
+  if (self->frame2)
+    {
+      gtk_widget_destroy (GTK_WIDGET (self->frame2));
+      self->frame2 = NULL;
+    }
 
   g_clear_object (&self->document);
+
+  GTK_WIDGET_CLASS (ide_editor_view_parent_class)->destroy (widget);
+
+  IDE_EXIT;
 }
 
 static void
diff --git a/libide/ide-buffer.c b/libide/ide-buffer.c
index 6fec000..ca24292 100644
--- a/libide/ide-buffer.c
+++ b/libide/ide-buffer.c
@@ -2468,13 +2468,15 @@ ide_buffer_release (IdeBuffer *self)
 {
   IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
 
+  IDE_ENTRY;
+
   g_return_if_fail (IDE_IS_BUFFER (self));
   g_return_if_fail (priv->hold_count >= 0);
 
   priv->hold_count--;
 
   if (priv->context == NULL)
-    return;
+    IDE_EXIT;
 
   /*
    * If our hold count has reached zero, then queue the buffer for
@@ -2490,6 +2492,8 @@ ide_buffer_release (IdeBuffer *self)
                                                          ide_buffer_reclaim_timeout,
                                                          self);
     }
+
+  IDE_EXIT;
 }
 
 /**
diff --git a/libide/ide-layout-stack-actions.c b/libide/ide-layout-stack-actions.c
index 062f10d..5085aa8 100644
--- a/libide/ide-layout-stack-actions.c
+++ b/libide/ide-layout-stack-actions.c
@@ -26,26 +26,32 @@
 #include "ide-layout-stack-private.h"
 #include "ide-layout-view.h"
 
-static void
-ide_layout_stack_actions_close_cb (GObject      *object,
-                                   GAsyncResult *result,
-                                   gpointer      user_data)
+static gboolean
+ide_layout_stack_actions_close_cb (gpointer data)
 {
-  IdeLayoutStack *self = (IdeLayoutStack *)object;
-  g_autoptr(IdeLayout) view = user_data;
+  struct {
+    IdeLayoutStack *self;
+    GtkWidget *active_view;
+  } *pair = data;
 
-  g_assert (IDE_IS_LAYOUT_STACK (self));
-  g_assert (IDE_IS_LAYOUT_VIEW (view));
+  g_assert (pair != NULL);
+  g_assert (IDE_IS_LAYOUT_STACK (pair->self));
+  g_assert (IDE_IS_LAYOUT_VIEW (pair->active_view));
 
-  ide_layout_stack_remove (self, GTK_WIDGET (view));
+  ide_layout_stack_remove (pair->self, GTK_WIDGET (pair->active_view));
 
   /*
    * Force the view to destroy. This helps situation where plugins are holding
    * onto a reference that can't easily be broken automatically.
    */
-  gtk_widget_destroy (GTK_WIDGET (view));
-}
+  gtk_widget_destroy (GTK_WIDGET (pair->active_view));
 
+  g_object_unref (pair->self);
+  g_object_unref (pair->active_view);
+  g_slice_free1 (sizeof *pair, pair);
+
+  return G_SOURCE_REMOVE;
+}
 
 static void
 ide_layout_stack_actions_close (GSimpleAction *action,
@@ -55,6 +61,10 @@ ide_layout_stack_actions_close (GSimpleAction *action,
   g_autoptr(GTask) task = NULL;
   IdeLayoutStack *self = user_data;
   GtkWidget *active_view;
+  struct {
+    IdeLayoutStack *self;
+    GtkWidget *active_view;
+  } *pair;
 
   g_assert (IDE_IS_LAYOUT_STACK (self));
 
@@ -62,13 +72,14 @@ ide_layout_stack_actions_close (GSimpleAction *action,
   if (active_view == NULL || !IDE_IS_LAYOUT_VIEW (active_view))
     return;
 
-
   /*
    * Queue until we are out of this potential signalaction. (Which mucks things
    * up since it expects the be able to continue working with the widget).
    */
-  task = g_task_new (self, NULL, ide_layout_stack_actions_close_cb, g_object_ref (active_view));
-  g_task_return_boolean (task, TRUE);
+  pair = g_slice_alloc (sizeof *pair);
+  pair->self = g_object_ref (self);
+  pair->active_view = g_object_ref (active_view);
+  g_timeout_add (0, ide_layout_stack_actions_close_cb, pair);
 }
 
 static void
diff --git a/libide/ide-source-view.c b/libide/ide-source-view.c
index a4af452..71613ba 100644
--- a/libide/ide-source-view.c
+++ b/libide/ide-source-view.c
@@ -1597,11 +1597,13 @@ ide_source_view_unbind_buffer (IdeSourceView  *self,
 {
   IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
 
+  IDE_ENTRY;
+
   g_assert (IDE_IS_SOURCE_VIEW (self));
   g_assert (EGG_IS_SIGNAL_GROUP (group));
 
   if (priv->buffer == NULL)
-    return;
+    IDE_EXIT;
 
   priv->scroll_mark = NULL;
 
@@ -1627,6 +1629,8 @@ ide_source_view_unbind_buffer (IdeSourceView  *self,
   g_clear_object (&priv->definition_highlight_end_mark);
 
   ide_buffer_release (priv->buffer);
+
+  IDE_EXIT;
 }
 
 static gunichar


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