aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--embed/downloader-view.c17
-rw-r--r--embed/ephy-embed-shell.c40
-rw-r--r--embed/ephy-embed-shell.h4
-rw-r--r--src/ephy-main.c23
-rw-r--r--src/ephy-window.c12
5 files changed, 55 insertions, 41 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 */
diff --git a/src/ephy-main.c b/src/ephy-main.c
index 5daca6fc6..493eb91dc 100644
--- a/src/ephy-main.c
+++ b/src/ephy-main.c
@@ -238,16 +238,6 @@ handle_email (GtkAboutDialog *about,
}
static void
-shell_weak_notify (gpointer data,
- GObject *zombie)
-{
- if (gtk_main_level ())
- {
- gtk_main_quit ();
- }
-}
-
-static void
unref_proxy_reply_cb (DBusGProxy *proxy,
GError *error,
gpointer user_data)
@@ -468,6 +458,12 @@ save_accels (void)
g_free (filename);
}
+static void
+shell_quit_cb (EphyShell *shell, gpointer data)
+{
+ gtk_main_quit ();
+}
+
int
main (int argc,
char *argv[])
@@ -767,13 +763,10 @@ main (int argc,
/* Now create the shell */
_ephy_shell_create_instance ();
+ g_signal_connect (ephy_shell, "quit", G_CALLBACK (shell_quit_cb), NULL);
queue_commands (user_time);
- /* We'll release the initial reference on idle */
- g_object_weak_ref (G_OBJECT (ephy_shell), shell_weak_notify, NULL);
- ephy_object_idle_unref (ephy_shell);
-
#ifdef HAVE_LIBNOTIFY
/* Init notifications for the download manager */
notify_init (PACKAGE);
@@ -782,6 +775,8 @@ main (int argc,
gtk_main ();
/* Shutdown */
+ g_object_unref (ephy_shell);
+
#ifdef HAVE_LIBNOTIFY
if (notify_is_initted ())
notify_uninit ();
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 3f53fa39d..df0c7dfb1 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -458,7 +458,6 @@ struct _EphyWindowPrivate
guint is_popup : 1;
guint present_on_insert : 1;
guint key_theme_is_emacs : 1;
- guint shell_unref : 1;
};
enum
@@ -3315,15 +3314,6 @@ ephy_window_dispose (GObject *object)
destroy_fullscreen_popup (window);
G_OBJECT_CLASS (ephy_window_parent_class)->dispose (object);
-
- /* We need to unref the shell after chaining up to the parent
- * class, since our children widgets might need the shell to
- * be around for some cleanup operations */
- if (window->priv->shell_unref == FALSE)
- {
- g_object_unref (ephy_shell);
- window->priv->shell_unref = TRUE;
- }
}
static void
@@ -3642,7 +3632,7 @@ ephy_window_init (EphyWindow *window)
{
LOG ("EphyWindow initialising %p", window);
- g_object_ref (ephy_shell);
+ _ephy_embed_shell_track_object (EPHY_EMBED_SHELL (ephy_shell), G_OBJECT (window));
window->priv = EPHY_WINDOW_GET_PRIVATE (window);
}