diff options
author | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2020-07-27 20:47:45 -0300 |
---|---|---|
committer | Juan Pablo Ugarte <juanpablougarte@gmail.com> | 2020-07-27 20:57:40 -0300 |
commit | cce40a8243ad926e4655508f91ef2d8a3be8beb5 (patch) | |
tree | f0f91bfe60ba46e6507c77a8aacf22fde3572ea7 /gladeui | |
parent | 61ab43edae89645137f3e017ae5e15b28b1eb725 (diff) | |
download | glade-cce40a8243ad926e4655508f91ef2d8a3be8beb5.tar.gz |
GladeProject: cleanup project finalization
Call gtk_widget_destroy() on GtkWindow derived objects to
avoid gtk keeping an internal reference
Fix issue #363 "Toplevel windows are leaked when closing a project"
Diffstat (limited to 'gladeui')
-rw-r--r-- | gladeui/glade-project.c | 49 |
1 files changed, 16 insertions, 33 deletions
diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c index 2d6199cd..94505b9e 100644 --- a/gladeui/glade-project.c +++ b/gladeui/glade-project.c @@ -247,37 +247,16 @@ glade_project_list_unref (GList *original_list) } static void -unparent_objects_recurse (GladeWidget *widget) -{ - GladeWidget *child; - GList *children, *list; - - /* Unparent all children */ - if ((children = glade_widget_get_children (widget)) != NULL) - { - for (list = children; list; list = list->next) - { - child = glade_widget_get_from_gobject (list->data); - - unparent_objects_recurse (child); - - if (!glade_widget_get_internal (child)) - glade_widget_remove_child (widget, child); - } - g_list_free (children); - } -} - -static void glade_project_dispose (GObject *object) { GladeProject *project = GLADE_PROJECT (object); GladeProjectPrivate *priv = project->priv; - GList *list, *tree; /* Emit close signal */ g_signal_emit (object, glade_project_signals[CLOSE], 0); + gtk_widget_destroy (priv->prefs_dialog); + /* Destroy running previews */ if (priv->previews) { @@ -298,17 +277,19 @@ glade_project_dispose (GObject *object) priv->undo_stack = NULL; /* Remove objects from the project */ - tree = g_list_copy (priv->tree); - for (list = tree; list; list = list->next) + while (priv->tree) { - GladeWidget *gwidget = glade_widget_get_from_gobject (list->data); + GObject *toplevel = priv->tree->data; - unparent_objects_recurse (gwidget); - } - g_list_free (tree); + glade_project_remove_object (project, toplevel); - while (priv->tree) - glade_project_remove_object (project, priv->tree->data); + /* NOTE: Due to Gtk+ keeping a reference to the window internally, + * gtk_window_new() does not return a reference to the caller. + * To delete a GtkWindow, call gtk_widget_destroy(). + */ + if (GTK_IS_WINDOW (toplevel)) + gtk_widget_destroy (GTK_WIDGET (toplevel)); + } while (priv->objects) glade_project_remove_object (project, priv->objects->data); @@ -342,8 +323,6 @@ glade_project_finalize (GObject *object) GladeProject *project = GLADE_PROJECT (object); GladeProjectPrivate *priv = project->priv; - gtk_widget_destroy (priv->prefs_dialog); - g_free (priv->path); g_free (priv->license); g_free (priv->css_provider_path); @@ -4149,6 +4128,10 @@ glade_project_remove_object (GladeProject *project, GObject *object) g_list_free (children); } + /* Update UI since this could take a while, specially disposing a large project */ + while (gtk_events_pending ()) + gtk_main_iteration (); + /* Remove selection and release name from the name context */ glade_project_selection_remove (project, object, TRUE); glade_project_release_widget_name (project, gwidget, |