[gnome-builder] layout-view: be more careful when closing views



commit 6941aab9261a4413d21012277a61b0c71722f5bd
Author: Christian Hergert <chergert redhat com>
Date:   Sun May 22 15:44:37 2016 +0300

    layout-view: be more careful when closing views
    
    We want to ensure that plugins are cleaned up before we get into our
    destroy cycle, so that we have a predictable place to cleanup state.

 libide/editor/ide-editor-view.c |   18 ++++++++++++++++++
 libide/ide-layout-stack.c       |   14 ++++++++++----
 libide/ide-layout-view.c        |   11 +++++++++++
 libide/ide-layout-view.h        |    4 ++++
 4 files changed, 43 insertions(+), 4 deletions(-)
---
diff --git a/libide/editor/ide-editor-view.c b/libide/editor/ide-editor-view.c
index 96ea8d2..ebb2595 100644
--- a/libide/editor/ide-editor-view.c
+++ b/libide/editor/ide-editor-view.c
@@ -841,6 +841,23 @@ ide_editor_view_destroy (GtkWidget *widget)
   IDE_EXIT;
 }
 
+static gboolean
+ide_editor_view_agree_to_close (IdeLayoutView *view)
+{
+  IdeEditorView *self = (IdeEditorView *)view;
+
+  g_assert (IDE_IS_EDITOR_VIEW (self));
+
+  /* We autosave documents, so we don't really need to ask the user
+   * to close the document. But we do need to release our plugins
+   * immediately before we start closing. Otherwise we rely on widget
+   * destruction which is a rather nasty way to cleanup.
+   */
+  ide_editor_view_unload_addins (self);
+
+  return TRUE;
+}
+
 static void
 ide_editor_view_finalize (GObject *object)
 {
@@ -916,6 +933,7 @@ ide_editor_view_class_init (IdeEditorViewClass *klass)
   view_class->set_back_forward_list = ide_editor_view_set_back_forward_list;
   view_class->navigate_to = ide_editor_view_navigate_to;
   view_class->get_title = ide_editor_view_get_title;
+  view_class->agree_to_close = ide_editor_view_agree_to_close;
 
   properties [PROP_DOCUMENT] =
     g_param_spec_object ("document",
diff --git a/libide/ide-layout-stack.c b/libide/ide-layout-stack.c
index 4a99b04..eb81e2e 100644
--- a/libide/ide-layout-stack.c
+++ b/libide/ide-layout-stack.c
@@ -81,14 +81,21 @@ void
 ide_layout_stack_remove (IdeLayoutStack *self,
                          GtkWidget      *view)
 {
-  GtkWidget *focus_after_close = NULL;
+  g_autoptr(GtkWidget) focus_after_close = NULL;
 
   g_return_if_fail (IDE_IS_LAYOUT_STACK (self));
   g_return_if_fail (IDE_IS_LAYOUT_VIEW (view));
 
   g_object_ref (view);
 
-  focus_after_close = g_list_nth_data (self->focus_history, 1);
+  if (!ide_layout_view_agree_to_close (IDE_LAYOUT_VIEW (view)))
+    return;
+
+  if (self->focus_history->data != view)
+    focus_after_close = self->focus_history->data;
+  else
+    focus_after_close = g_list_nth_data (self->focus_history, 1);
+
   if (focus_after_close != NULL)
     g_object_ref (focus_after_close);
 
@@ -99,9 +106,8 @@ ide_layout_stack_remove (IdeLayoutStack *self,
     {
       gtk_stack_set_visible_child (self->stack, focus_after_close);
       gtk_widget_grab_focus (GTK_WIDGET (focus_after_close));
-      g_clear_object (&focus_after_close);
     }
-  else
+  else if (!gtk_widget_in_destruction (GTK_WIDGET (self)))
     {
       GtkStyleContext *context;
 
diff --git a/libide/ide-layout-view.c b/libide/ide-layout-view.c
index 6bd6564..22b29c3 100644
--- a/libide/ide-layout-view.c
+++ b/libide/ide-layout-view.c
@@ -343,3 +343,14 @@ ide_layout_view_get_special_title (IdeLayoutView *self)
 
   return ret;
 }
+
+gboolean
+ide_layout_view_agree_to_close (IdeLayoutView *self)
+{
+  g_return_val_if_fail (IDE_IS_LAYOUT_VIEW (self), FALSE);
+
+  if (IDE_LAYOUT_VIEW_GET_CLASS (self)->agree_to_close)
+    return IDE_LAYOUT_VIEW_GET_CLASS (self)->agree_to_close (self);
+
+  return TRUE;
+}
diff --git a/libide/ide-layout-view.h b/libide/ide-layout-view.h
index 76d712a..8a99fa1 100644
--- a/libide/ide-layout-view.h
+++ b/libide/ide-layout-view.h
@@ -46,8 +46,12 @@ struct _IdeLayoutViewClass
                                            IdeBackForwardList        *back_forward_list);
   void           (*navigate_to)           (IdeLayoutView             *self,
                                            IdeSourceLocation         *location);
+  gboolean       (*agree_to_close)        (IdeLayoutView             *self);
+
+  gpointer padding[8];
 };
 
+gboolean       ide_layout_view_agree_to_close        (IdeLayoutView             *self);
 IdeLayoutView *ide_layout_view_create_split          (IdeLayoutView             *self);
 gboolean       ide_layout_view_get_can_preview       (IdeLayoutView             *self);
 gboolean       ide_layout_view_get_can_split         (IdeLayoutView             *self);


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