aboutsummaryrefslogtreecommitdiffstats
path: root/embed
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
parentdc14e5bcab1759813aeed64af213ba067535e7e8 (diff)
downloadgsoc2013-epiphany-46845bbcf412994f0bb3e949178c6f72f676f70b.tar
gsoc2013-epiphany-46845bbcf412994f0bb3e949178c6f72f676f70b.tar.gz
gsoc2013-epiphany-46845bbcf412994f0bb3e949178c6f72f676f70b.tar.bz2
gsoc2013-epiphany-46845bbcf412994f0bb3e949178c6f72f676f70b.tar.lz
gsoc2013-epiphany-46845bbcf412994f0bb3e949178c6f72f676f70b.tar.xz
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')
-rw-r--r--embed/downloader-view.c17
-rw-r--r--embed/ephy-embed-shell.c40
-rw-r--r--embed/ephy-embed-shell.h4
3 files changed, 45 insertions, 16 deletions
diff --git a/embed/downloader-view.c b/embed/downloader-view.c
index da28caf23..a2f655807 100644
--- a/embed/downloader-view.c
+++ b/embed/downloader-view.c
@@ -74,7 +74,6 @@ struct _DownloaderViewPrivate
NotifyNotification *notification;
#endif
- guint idle_unref : 1;
guint source_id;
guint notification_timeout;
};
@@ -222,8 +221,6 @@ prepare_close_cb (EphyEmbedShell *shell,
/* hide window already */
gtk_widget_hide (priv->window);
- priv->idle_unref = FALSE;
-
/* cancel pending downloads */
g_hash_table_foreach_remove (priv->downloads_hash,
(GHRFunc) remove_download, view);
@@ -237,14 +234,12 @@ prepare_close_cb (EphyEmbedShell *shell,
static void
downloader_view_init (DownloaderView *dv)
{
- g_object_ref (embed_shell);
-
+ _ephy_embed_shell_track_object (embed_shell, G_OBJECT (dv));
dv->priv = EPHY_DOWNLOADER_VIEW_GET_PRIVATE (dv);
dv->priv->downloads_hash = g_hash_table_new_full
(g_direct_hash, g_direct_equal, NULL,
(GDestroyNotify)gtk_tree_row_reference_free);
- dv->priv->idle_unref = TRUE;
downloader_view_build_ui (dv);
@@ -259,7 +254,6 @@ downloader_view_finalize (GObject *object)
{
DownloaderView *dv = EPHY_DOWNLOADER_VIEW (object);
DownloaderViewPrivate *priv = dv->priv;
- gboolean idle_unref = dv->priv->idle_unref;
if (priv->status_icon != NULL)
{
@@ -286,15 +280,6 @@ downloader_view_finalize (GObject *object)
g_hash_table_destroy (dv->priv->downloads_hash);
G_OBJECT_CLASS (downloader_view_parent_class)->finalize (object);
-
- if (idle_unref)
- {
- ephy_object_idle_unref (embed_shell);
- }
- else
- {
- g_object_unref (embed_shell);
- }
}
DownloaderView *
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++;
+}
diff --git a/embed/ephy-embed-shell.h b/embed/ephy-embed-shell.h
index 9772293b3..ef10c2acc 100644
--- a/embed/ephy-embed-shell.h
+++ b/embed/ephy-embed-shell.h
@@ -91,6 +91,10 @@ void ephy_embed_shell_set_print_settings (EphyEmbedShell *shell,
GtkPrintSettings *ephy_embed_shell_get_print_settings (EphyEmbedShell *shell);
+/* Private API */
+void _ephy_embed_shell_track_object (EphyEmbedShell *shell,
+ GObject *object);
+
G_END_DECLS
#endif /* !EPHY_EMBED_SHELL_H */