summaryrefslogtreecommitdiff
path: root/gladeui
diff options
context:
space:
mode:
authorJuan Pablo Ugarte <juanpablougarte@gmail.com>2020-07-27 20:47:45 -0300
committerJuan Pablo Ugarte <juanpablougarte@gmail.com>2020-07-27 20:57:40 -0300
commitcce40a8243ad926e4655508f91ef2d8a3be8beb5 (patch)
treef0f91bfe60ba46e6507c77a8aacf22fde3572ea7 /gladeui
parent61ab43edae89645137f3e017ae5e15b28b1eb725 (diff)
downloadglade-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.c49
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,