[glade] GladeProject: cleanup dispose
- From: Juan Pablo Ugarte <jpu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glade] GladeProject: cleanup dispose
- Date: Wed, 5 Aug 2020 22:39:26 +0000 (UTC)
commit 7aa34400724a7b4692af22b4a669a6a41395f62b
Author: Juan Pablo Ugarte <juanpablougarte gmail com>
Date: Wed Aug 5 19:32:32 2020 -0300
GladeProject: cleanup dispose
GladeAdaptorChooserWidget: use g_object_add_weak_pointer() instead of
g_object_weak_ref() and unset project on dispose.
GladeDesignLayout, GladeDesignView: use g_object_add_weak_pointer()
GladeEditable: fix project signal disconnect issue
gladeui/glade-adaptor-chooser-widget.c | 28 +++++----
gladeui/glade-design-layout.c | 36 +++++++-----
gladeui/glade-design-view.c | 6 +-
gladeui/glade-editable.c | 6 +-
gladeui/glade-project.c | 101 ++++++++++++++++++---------------
5 files changed, 96 insertions(+), 81 deletions(-)
---
diff --git a/gladeui/glade-adaptor-chooser-widget.c b/gladeui/glade-adaptor-chooser-widget.c
index cdfa59422..545e86856 100644
--- a/gladeui/glade-adaptor-chooser-widget.c
+++ b/gladeui/glade-adaptor-chooser-widget.c
@@ -89,13 +89,20 @@ _glade_adaptor_chooser_widget_init (_GladeAdaptorChooserWidget *chooser)
gtk_widget_init_template (GTK_WIDGET (chooser));
}
+static void
+_glade_adaptor_chooser_widget_dispose (GObject *object)
+{
+ _glade_adaptor_chooser_widget_set_project (GLADE_ADAPTOR_CHOOSER_WIDGET (object), NULL);
+
+ G_OBJECT_CLASS (_glade_adaptor_chooser_widget_parent_class)->dispose (object);
+}
+
static void
_glade_adaptor_chooser_widget_finalize (GObject *object)
{
_GladeAdaptorChooserWidgetPrivate *priv = GET_PRIVATE (object);
g_clear_pointer (&priv->search_text, g_free);
- g_clear_object (&priv->project);
G_OBJECT_CLASS (_glade_adaptor_chooser_widget_parent_class)->finalize (object);
}
@@ -513,6 +520,7 @@ _glade_adaptor_chooser_widget_class_init (_GladeAdaptorChooserWidgetClass *klass
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ object_class->dispose = _glade_adaptor_chooser_widget_dispose;
object_class->finalize = _glade_adaptor_chooser_widget_finalize;
object_class->set_property = _glade_adaptor_chooser_widget_set_property;
object_class->get_property = _glade_adaptor_chooser_widget_get_property;
@@ -574,15 +582,6 @@ _glade_adaptor_chooser_widget_new (_GladeAdaptorChooserWidgetFlags flags, GladeP
NULL));
}
-static void
-on_project_weak_notify (gpointer data, GObject *project)
-{
- _GladeAdaptorChooserWidget *chooser = data;
- _GladeAdaptorChooserWidgetPrivate *priv = GET_PRIVATE (chooser);
-
- priv->project = NULL;
-}
-
void
_glade_adaptor_chooser_widget_set_project (_GladeAdaptorChooserWidget *chooser,
GladeProject *project)
@@ -594,18 +593,17 @@ _glade_adaptor_chooser_widget_set_project (_GladeAdaptorChooserWidget *chooser,
if (priv->project)
{
- g_object_weak_unref (G_OBJECT (priv->project), on_project_weak_notify, chooser);
+ g_object_remove_weak_pointer (G_OBJECT (priv->project), (gpointer *) &priv->project);
priv->project = NULL;
}
if (project)
{
priv->project = project;
- g_object_weak_ref (G_OBJECT (project), on_project_weak_notify, chooser);
- }
+ g_object_add_weak_pointer (G_OBJECT (project), (gpointer *) &priv->project);
-
- gtk_tree_model_filter_refilter (priv->treemodelfilter);
+ gtk_tree_model_filter_refilter (priv->treemodelfilter);
+ }
}
void
diff --git a/gladeui/glade-design-layout.c b/gladeui/glade-design-layout.c
index edccdb76b..5fec0d6ff 100644
--- a/gladeui/glade-design-layout.c
+++ b/gladeui/glade-design-layout.c
@@ -1841,13 +1841,7 @@ glade_design_layout_set_property (GObject *object,
switch (prop_id)
{
case PROP_DESIGN_VIEW:
- {
- priv->view = GLADE_DESIGN_VIEW (g_value_get_object (value));
- priv->project = glade_design_view_get_project (priv->view);
- g_signal_connect (priv->project, "notify::pointer-mode",
- G_CALLBACK (on_pointer_mode_notify),
- GLADE_DESIGN_LAYOUT (object));
- }
+ priv->view = GLADE_DESIGN_VIEW (g_value_get_object (value));
break;
default:
@@ -1907,8 +1901,15 @@ glade_design_layout_constructor (GType type,
self = GLADE_DESIGN_LAYOUT (object);
priv = glade_design_layout_get_instance_private (self);
- g_signal_connect (priv->project,
- "selection-changed",
+ /* Keep a weak reference to project */
+ priv->project = glade_design_view_get_project (priv->view);
+ g_object_add_weak_pointer (G_OBJECT (priv->project), (gpointer *) &priv->project);
+
+ g_signal_connect (priv->project, "notify::pointer-mode",
+ G_CALLBACK (on_pointer_mode_notify),
+ self);
+
+ g_signal_connect (priv->project, "selection-changed",
G_CALLBACK (on_project_selection_changed),
self);
@@ -1941,12 +1942,17 @@ glade_design_layout_finalize (GObject *object)
g_clear_object (&priv->default_context);
g_clear_object (&priv->drag_dest);
- g_signal_handlers_disconnect_by_func (priv->project,
- on_project_selection_changed,
- layout);
- g_signal_handlers_disconnect_by_func (priv->project,
- on_pointer_mode_notify,
- layout);
+ if (priv->project)
+ {
+ g_signal_handlers_disconnect_by_func (priv->project,
+ on_project_selection_changed,
+ layout);
+ g_signal_handlers_disconnect_by_func (priv->project,
+ on_pointer_mode_notify,
+ layout);
+
+ priv->project = NULL;
+ }
G_OBJECT_CLASS (glade_design_layout_parent_class)->finalize (object);
}
diff --git a/gladeui/glade-design-view.c b/gladeui/glade-design-view.c
index da24037ef..82887ac59 100644
--- a/gladeui/glade-design-view.c
+++ b/gladeui/glade-design-view.c
@@ -252,19 +252,23 @@ glade_design_view_set_project (GladeDesignView *view, GladeProject *project)
if (priv->project)
{
+ g_object_remove_weak_pointer (G_OBJECT (priv->project), (gpointer *) &priv->project);
+
g_signal_handlers_disconnect_by_data (priv->project, view);
g_signal_handlers_disconnect_by_data (priv->project, priv->scrolled_window);
g_object_set_data (G_OBJECT (priv->project), GLADE_DESIGN_VIEW_KEY, NULL);
}
- g_set_object (&priv->project, project);
+ priv->project = project;
if (!project)
return;
g_assert (GLADE_IS_PROJECT (project));
+ g_object_add_weak_pointer (G_OBJECT (project), (gpointer *) &priv->project);
+
g_signal_connect (project, "add-widget",
G_CALLBACK (on_project_add_widget), view);
g_signal_connect (project, "remove-widget",
diff --git a/gladeui/glade-editable.c b/gladeui/glade-editable.c
index de345eec7..43458955a 100644
--- a/gladeui/glade-editable.c
+++ b/gladeui/glade-editable.c
@@ -79,7 +79,7 @@ glade_editable_load_default (GladeEditable *editable,
if (old_widget != widget)
{
- if (old_widget)
+ if (old_project)
{
g_signal_handlers_disconnect_by_func (old_project, G_CALLBACK (project_changed), editable);
g_signal_handlers_disconnect_by_func (old_project, G_CALLBACK (project_closed), editable);
@@ -95,9 +95,9 @@ glade_editable_load_default (GladeEditable *editable,
g_object_set_qdata (G_OBJECT (editable), glade_editable_widget_quark, widget);
g_object_set_qdata (G_OBJECT (editable), glade_editable_project_quark, project);
- g_signal_connect (project, "changed",
+ g_signal_connect (project, "changed",
G_CALLBACK (project_changed), editable);
- g_signal_connect (project, "close",
+ g_signal_connect (project, "close",
G_CALLBACK (project_closed), editable);
}
}
diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c
index 94505b9ee..6766b4190 100644
--- a/gladeui/glade-project.c
+++ b/gladeui/glade-project.c
@@ -255,7 +255,29 @@ glade_project_dispose (GObject *object)
/* Emit close signal */
g_signal_emit (object, glade_project_signals[CLOSE], 0);
- gtk_widget_destroy (priv->prefs_dialog);
+ /* Disconnect from model */
+#define MODEL_DISCONNECT(func) g_signal_handlers_disconnect_by_func (priv->model, G_CALLBACK (func), project)
+ MODEL_DISCONNECT (gtk_tree_model_row_changed);
+ MODEL_DISCONNECT (gtk_tree_model_row_inserted);
+ MODEL_DISCONNECT (gtk_tree_model_row_has_child_toggled);
+ MODEL_DISCONNECT (gtk_tree_model_row_deleted);
+ MODEL_DISCONNECT (gtk_tree_model_rows_reordered);
+
+ /* Destroy preferences dialog */
+ g_clear_pointer (&priv->prefs_dialog, gtk_widget_destroy);
+
+ /* Clear selection */
+ g_clear_pointer (&priv->selection, g_list_free);
+ g_clear_handle_id (&priv->selection_changed_id, g_source_remove);
+
+ /* Clear undo/redo stack */
+ g_clear_pointer (&priv->undo_stack, glade_project_list_unref);
+
+ /* NOTE: prev_redo_item and first_modification always point to undo_stack
+ * So we should never try to free it
+ */
+ priv->prev_redo_item = NULL;
+ priv->first_modification = NULL;
/* Destroy running previews */
if (priv->previews)
@@ -264,17 +286,8 @@ glade_project_dispose (GObject *object)
priv->previews = NULL;
}
- if (priv->selection_changed_id > 0)
- priv->selection_changed_id =
- (g_source_remove (priv->selection_changed_id), 0);
-
- glade_project_selection_clear (project, TRUE);
-
g_clear_object (&priv->css_provider);
g_clear_object (&priv->css_monitor);
-
- glade_project_list_unref (priv->undo_stack);
- priv->undo_stack = NULL;
/* Remove objects from the project */
while (priv->tree)
@@ -283,11 +296,11 @@ glade_project_dispose (GObject *object)
glade_project_remove_object (project, toplevel);
- /* 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().
+ /*
+ * FIXME: GladeWidgets are leaked so this is a workaround to make sure
+ * at least the runtime widgets (including windows) are destroyed!
*/
- if (GTK_IS_WINDOW (toplevel))
+ if (GTK_IS_WIDGET (toplevel))
gtk_widget_destroy (GTK_WIDGET (toplevel));
}
@@ -296,6 +309,7 @@ glade_project_dispose (GObject *object)
g_assert (priv->tree == NULL);
g_assert (priv->objects == NULL);
+ g_assert (gtk_tree_model_iter_n_children (priv->model, NULL) == 0);
if (priv->unknown_catalogs)
{
@@ -313,7 +327,7 @@ glade_project_dispose (GObject *object)
}
g_object_unref (priv->model);
-
+
G_OBJECT_CLASS (glade_project_parent_class)->dispose (object);
}
@@ -1662,7 +1676,7 @@ glade_project_read_comment_properties (GladeProject *project,
GladeXmlNode *root_node)
{
GladeProjectPrivate *priv = project->priv;
- gchar *license, *name, *description, *copyright, *authors;
+ g_autofree gchar *license = NULL, *name = NULL, *description = NULL, *copyright = NULL, *authors = NULL;
GladeXmlNode *node;
license = name = description = copyright = authors = NULL;
@@ -1706,17 +1720,13 @@ glade_project_read_comment_properties (GladeProject *project,
g_free (val);
}
- _glade_project_properties_set_license_data (GLADE_PROJECT_PROPERTIES (priv->prefs_dialog),
- license,
- name,
- description,
- copyright,
- authors);
- g_free (license);
- g_free (name);
- g_free (description);
- g_free (copyright);
- g_free (authors);
+ if (priv->prefs_dialog)
+ _glade_project_properties_set_license_data (GLADE_PROJECT_PROPERTIES (priv->prefs_dialog),
+ license,
+ name,
+ description,
+ copyright,
+ authors);
}
static inline void
@@ -2210,7 +2220,9 @@ glade_project_update_properties_title (GladeProject *project)
/* Update prefs dialogs here... */
name = glade_project_get_name (project);
title = g_strdup_printf (_("%s document properties"), name);
- gtk_window_set_title (GTK_WINDOW (project->priv->prefs_dialog), title);
+
+ if (project->priv->prefs_dialog)
+ gtk_window_set_title (GTK_WINDOW (project->priv->prefs_dialog), title);
g_free (title);
g_free (name);
}
@@ -2392,7 +2404,10 @@ glade_project_write_license_data (GladeProject *project,
GladeXmlContext *context,
GladeXmlNode *root)
{
- gchar *license, *name, *description, *copyright, *authors;
+ g_autofree gchar *license = NULL, *name = NULL, *description = NULL, *copyright = NULL, *authors = NULL;
+
+ if (!project->priv->prefs_dialog)
+ return;
_glade_project_properties_get_license_data (GLADE_PROJECT_PROPERTIES (project->priv->prefs_dialog),
&license,
@@ -2401,9 +2416,6 @@ glade_project_write_license_data (GladeProject *project,
©right,
&authors);
- if (!license)
- return;
-
glade_project_write_comment_property (project, context, root,
"interface-license-type",
license);
@@ -2419,12 +2431,6 @@ glade_project_write_license_data (GladeProject *project,
glade_project_write_comment_property (project, context, root,
"interface-authors",
authors);
-
- g_free (license);
- g_free (name);
- g_free (description);
- g_free (copyright);
- g_free (authors);
}
static gint
@@ -4410,17 +4416,16 @@ glade_project_selection_changed (GladeProject *project)
glade_project_signals[SELECTION_CHANGED], 0);
/* Cancel any idle we have */
- if (project->priv->selection_changed_id > 0)
- project->priv->selection_changed_id =
- (g_source_remove (project->priv->selection_changed_id), 0);
+ g_clear_handle_id (&project->priv->selection_changed_id, g_source_remove);
}
static gboolean
-selection_change_idle (GladeProject *project)
+selection_change_idle (gpointer data)
{
+ GladeProject *project = data;
project->priv->selection_changed_id = 0;
glade_project_selection_changed (project);
- return FALSE;
+ return G_SOURCE_REMOVE;
}
void
@@ -4428,9 +4433,10 @@ glade_project_queue_selection_changed (GladeProject *project)
{
g_return_if_fail (GLADE_IS_PROJECT (project));
- if (project->priv->selection_changed_id == 0)
- project->priv->selection_changed_id =
- g_idle_add ((GSourceFunc) selection_change_idle, project);
+ if (project->priv->selection_changed_id)
+ return;
+
+ project->priv->selection_changed_id = g_idle_add (selection_change_idle, project);
}
static void
@@ -5025,7 +5031,8 @@ glade_project_properties (GladeProject *project)
{
g_return_if_fail (GLADE_IS_PROJECT (project));
- gtk_window_present (GTK_WINDOW (project->priv->prefs_dialog));
+ if (project->priv->prefs_dialog)
+ gtk_window_present (GTK_WINDOW (project->priv->prefs_dialog));
}
gchar *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]