aboutsummaryrefslogtreecommitdiffstats
path: root/embed/ephy-embed-shell.c
diff options
context:
space:
mode:
authorXan Lopez <xan@gnome.org>2009-10-23 07:51:17 +0800
committerXan Lopez <xan@gnome.org>2009-10-24 02:56:24 +0800
commit46845bbcf412994f0bb3e949178c6f72f676f70b (patch)
tree998ead5ff6fd8a86269e45313a2baa3d2afd182b /embed/ephy-embed-shell.c
parentdc14e5bcab1759813aeed64af213ba067535e7e8 (diff)
downloadgsoc2013-epiphany-46845bbcf412994f0bb3e949178c6f72f676f70b.tar.gz
gsoc2013-epiphany-46845bbcf412994f0bb3e949178c6f72f676f70b.tar.zst
gsoc2013-epiphany-46845bbcf412994f0bb3e949178c6f72f676f70b.zip
Refactor EphyShell lifetime tracking
Stop having each EphyWindow ref the shell, and instead have the shell track all the newly created EphyWindows. When the last one is gone, quit the GTK+ mainloop. This is simpler and avoids potential reference cycles (see bug #573551). Bug #599348
Diffstat (limited to 'embed/ephy-embed-shell.c')
-rw-r--r--embed/ephy-embed-shell.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 85eb7fa2e..17f4b98e2 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -57,12 +57,14 @@ struct _EphyEmbedShellPrivate
EphyAdBlockManager *adblock_manager;
GtkPageSetup *page_setup;
GtkPrintSettings *print_settings;
+ guint object_count;
guint single_initialised : 1;
};
enum
{
PREPARE_CLOSE,
+ QUIT,
LAST_SIGNAL
};
@@ -315,6 +317,25 @@ ephy_embed_shell_class_init (EphyEmbedShellClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+
+/**
+ * EphyEmbedShell::quit:
+ * @shell: an #EphyEmbedShell
+ *
+ * The ::quit is emitted when all windows (browser windows, popups,
+ * download windows, etc) are closed and the @shell is ready to be
+ * closed.
+ *
+ * Since: 2.30
+ **/
+ signals[QUIT] =
+ g_signal_new ("quit",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
g_type_class_add_private (object_class, sizeof (EphyEmbedShellPrivate));
}
@@ -490,3 +511,22 @@ ephy_embed_shell_get_print_settings (EphyEmbedShell *shell)
return priv->print_settings;
}
+
+
+static void
+object_notify_cb (EphyEmbedShell *shell, GObject *object)
+{
+ shell->priv->object_count--;
+ if (shell->priv->object_count == 0)
+ g_signal_emit (shell, signals[QUIT], 0);
+}
+
+void
+_ephy_embed_shell_track_object (EphyEmbedShell *shell, GObject *object)
+{
+ g_return_if_fail (EPHY_IS_EMBED_SHELL (shell));
+ g_return_if_fail (G_IS_OBJECT (object));
+
+ g_object_weak_ref (object, (GWeakNotify)object_notify_cb, shell);
+ shell->priv->object_count++;
+}