aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog24
-rw-r--r--doc/reference/tmpl/ephy-embed.sgml2
-rw-r--r--embed/downloader-view.c62
-rw-r--r--embed/ephy-embed-shell.c33
-rw-r--r--embed/ephy-embed-shell.h4
-rw-r--r--embed/ephy-favicon-cache.c18
-rw-r--r--embed/mozilla/mozilla-embed-find.cpp3
-rw-r--r--embed/mozilla/mozilla-embed-single.cpp19
-rw-r--r--embed/mozilla/mozilla-embed.cpp13
-rw-r--r--embed/mozilla/mozilla-notifiers.cpp6
-rw-r--r--embed/mozilla/mozilla-notifiers.h3
-rw-r--r--src/ephy-session.c64
-rw-r--r--src/ephy-shell.c19
-rw-r--r--src/ephy-window.c3
14 files changed, 223 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index 27e42f114..201c1c207 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2005-07-04 Christian Persch <chpe@cvs.gnome.org>
+
+ * embed/downloader-view.c: (remove_download), (prepare_close_cb),
+ (downloader_view_init), (downloader_view_finalize),
+ (downloader_view_remove_download), (download_dialog_delete_cb):
+ * embed/ephy-embed-shell.c: (ephy_embed_shell_prepare_close),
+ (ephy_embed_shell_class_init):
+ * embed/ephy-embed-shell.h:
+ * embed/ephy-favicon-cache.c: (prepare_close_cb),
+ (ephy_favicon_cache_init), (kill_download):
+ * embed/mozilla/mozilla-embed-find.cpp:
+ * embed/mozilla/mozilla-embed-single.cpp:
+ * embed/mozilla/mozilla-embed.cpp:
+ * embed/mozilla/mozilla-notifiers.cpp:
+ * embed/mozilla/mozilla-notifiers.h:
+ * src/ephy-session.c: (ephy_session_init), (ephy_session_dispose),
+ (ephy_session_autoresume), (close_dialog), (ephy_session_close):
+ * src/ephy-shell.c: (ephy_shell_startup), (toolwindow_hide_cb):
+ * src/ephy-window.c: (ephy_window_finalize):
+
+ Better fix for bug #151037 to make session shutdown work again.
+ Also fix session shutdown while resuming, and preserve the session
+ in this case.
+
2005-07-03 Jean-François Rameau <jframeau@cvs.gnome.org>
* embed/ephy-cookie-manager.h:
diff --git a/doc/reference/tmpl/ephy-embed.sgml b/doc/reference/tmpl/ephy-embed.sgml
index 6ff40c853..6ff26da6b 100644
--- a/doc/reference/tmpl/ephy-embed.sgml
+++ b/doc/reference/tmpl/ephy-embed.sgml
@@ -247,6 +247,8 @@ be done by casting).
@:
@:
@:
+@:
+@:
@:
<!-- ##### SIGNAL EphyEmbed::ge-search-key-press ##### -->
diff --git a/embed/downloader-view.c b/embed/downloader-view.c
index 7499264ed..9ec3ac2da 100644
--- a/embed/downloader-view.c
+++ b/embed/downloader-view.c
@@ -82,6 +82,8 @@ struct DownloaderViewPrivate
GtkWidget *abort_button;
EggStatusIcon *status_icon;
+
+ guint idle_unref : 1;
};
enum
@@ -207,33 +209,82 @@ show_status_icon (DownloaderView *dv)
G_CALLBACK(status_icon_popup_menu_cb), dv);
}
+static gboolean
+remove_download (EphyDownload *download,
+ gpointer rowref,
+ DownloaderView *view)
+{
+ g_signal_handlers_disconnect_matched
+ (download, G_SIGNAL_MATCH_DATA ,
+ 0, 0, NULL, NULL, view);
+ ephy_download_cancel (download);
+
+ g_object_unref (download);
+ return TRUE;
+}
+
+static void
+prepare_close_cb (EphyEmbedShell *shell,
+ DownloaderView *view)
+{
+ DownloaderViewPrivate *priv = view->priv;
+
+ /* the downloader owns a ref to itself, no need for another ref */
+
+ /* 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);
+
+ gtk_list_store_clear (GTK_LIST_STORE (priv->model));
+
+ /* drop the self reference */
+ g_object_unref (view);
+}
+
static void
downloader_view_init (DownloaderView *dv)
{
+ g_object_ref (embed_shell);
+
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);
show_status_icon (dv);
- g_object_ref (embed_shell);
+ g_signal_connect_object (embed_shell, "prepare_close",
+ G_CALLBACK (prepare_close_cb), dv, 0);
}
static void
downloader_view_finalize (GObject *object)
{
DownloaderView *dv = EPHY_DOWNLOADER_VIEW (object);
+ gboolean idle_unref = dv->priv->idle_unref;
g_object_unref (dv->priv->status_icon);
g_hash_table_destroy (dv->priv->downloads_hash);
G_OBJECT_CLASS (parent_class)->finalize (object);
- ephy_object_idle_unref (embed_shell);
+ if (idle_unref)
+ {
+ ephy_object_idle_unref (embed_shell);
+ }
+ else
+ {
+ g_object_unref (embed_shell);
+ }
}
DownloaderView *
@@ -709,7 +760,7 @@ downloader_view_remove_download (DownloaderView *dv, EphyDownload *download)
gtk_tree_path_free (path);
/* Removal */
-
+
gtk_list_store_remove (GTK_LIST_STORE (dv->priv->model), &iter2);
g_hash_table_remove (dv->priv->downloads_hash,
download);
@@ -734,7 +785,9 @@ downloader_view_remove_download (DownloaderView *dv, EphyDownload *download)
/* Close the dialog if there are no more downloads */
if (!g_hash_table_size (dv->priv->downloads_hash))
- g_object_unref (G_OBJECT (dv));
+ {
+ g_object_unref (dv);
+ }
}
void
@@ -765,6 +818,7 @@ gboolean
download_dialog_delete_cb (GtkWidget *window, GdkEventAny *event,
DownloaderView *dv)
{
+ /* FIXME multi-head */
if (egg_tray_manager_check_running (gdk_screen_get_default ()))
{
gtk_widget_hide (dv->priv->window);
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 8067bf0ea..600037c93 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -43,6 +43,14 @@ struct _EphyEmbedShellPrivate
EphyEncodings *encodings;
};
+enum
+{
+ PREPARE_CLOSE,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
static void ephy_embed_shell_class_init (EphyEmbedShellClass *klass);
static void ephy_embed_shell_init (EphyEmbedShell *shell);
@@ -204,6 +212,14 @@ ephy_embed_shell_get_encodings (EphyEmbedShell *shell)
return G_OBJECT (shell->priv->encodings);
}
+void
+ephy_embed_shell_prepare_close (EphyEmbedShell *shell)
+{
+ EphyEmbedShellPrivate *priv = shell->priv;
+
+ g_signal_emit (shell, signals[PREPARE_CLOSE], 0);
+}
+
static void
ephy_embed_shell_init (EphyEmbedShell *shell)
{
@@ -225,5 +241,22 @@ ephy_embed_shell_class_init (EphyEmbedShellClass *klass)
klass->get_embed_single = impl_get_embed_single;
+/**
+ * EphyEmbed::prepare-close:
+ * @shell:
+ *
+ * The ::prepare-close signal is emitted when epiphany is preparing to
+ * quit on command from the session manager. You can use it when you need
+ * to do something special (shut down a service, for example).
+ **/
+ signals[PREPARE_CLOSE] =
+ g_signal_new ("prepare-close",
+ EPHY_TYPE_EMBED_SHELL,
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EphyEmbedShellClass, prepare_close),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
g_type_class_add_private (object_class, sizeof (EphyEmbedShellPrivate));
}
diff --git a/embed/ephy-embed-shell.h b/embed/ephy-embed-shell.h
index b5897781f..d5369749c 100644
--- a/embed/ephy-embed-shell.h
+++ b/embed/ephy-embed-shell.h
@@ -51,6 +51,8 @@ struct _EphyEmbedShellClass
{
GObjectClass parent_class;
+ void (* prepare_close) (EphyEmbedShell *shell);
+
/*< private >*/
GObject * (* get_embed_single) (EphyEmbedShell *shell);
};
@@ -67,6 +69,8 @@ GObject *ephy_embed_shell_get_encodings (EphyEmbedShell *shell);
GObject *ephy_embed_shell_get_embed_single (EphyEmbedShell *shell);
+void ephy_embed_shell_prepare_close (EphyEmbedShell *shell);
+
G_END_DECLS
#endif /* !EPHY_EMBED_SHELL_H */
diff --git a/embed/ephy-favicon-cache.c b/embed/ephy-favicon-cache.c
index 83c14ffad..034ec305d 100644
--- a/embed/ephy-favicon-cache.c
+++ b/embed/ephy-favicon-cache.c
@@ -29,6 +29,7 @@
#include <time.h>
#include <sys/stat.h>
+#include "ephy-embed-shell.h"
#include "ephy-embed-persist.h"
#include "ephy-embed-factory.h"
#include "ephy-file-helpers.h"
@@ -44,6 +45,7 @@
static void ephy_favicon_cache_class_init (EphyFaviconCacheClass *klass);
static void ephy_favicon_cache_init (EphyFaviconCache *cache);
static void ephy_favicon_cache_finalize (GObject *object);
+static gboolean kill_download (const char*, EphyEmbedPersist*, EphyFaviconCache*);
#define EPHY_FAVICON_CACHE_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_FAVICON_CACHE, EphyFaviconCachePrivate))
@@ -205,6 +207,16 @@ remove_obsolete_icons (EphyFaviconCache *eb)
}
static void
+prepare_close_cb (EphyEmbedShell *shell,
+ EphyFaviconCache *cache)
+{
+ EphyFaviconCachePrivate *priv = cache->priv;
+
+ g_hash_table_foreach_remove (priv->downloads_hash,
+ (GHRFunc) kill_download, cache);
+}
+
+static void
ephy_favicon_cache_init (EphyFaviconCache *cache)
{
EphyNodeDb *db;
@@ -251,10 +263,14 @@ ephy_favicon_cache_init (EphyFaviconCache *cache)
ephy_node_db_load_from_file (cache->priv->db, cache->priv->xml_file,
EPHY_FAVICON_CACHE_XML_ROOT,
EPHY_FAVICON_CACHE_XML_VERSION);
+
+ /* listen to prepare-close on the shell */
+ g_signal_connect_object (embed_shell, "prepare-close",
+ G_CALLBACK (prepare_close_cb), cache, 0);
}
static gboolean
-kill_download (char *key,
+kill_download (const char *key,
EphyEmbedPersist *persist,
EphyFaviconCache *cache)
{
diff --git a/embed/mozilla/mozilla-embed-find.cpp b/embed/mozilla/mozilla-embed-find.cpp
index 92e755e2b..d039b4d69 100644
--- a/embed/mozilla/mozilla-embed-find.cpp
+++ b/embed/mozilla/mozilla-embed-find.cpp
@@ -28,7 +28,6 @@
#include "mozilla-embed-find.h"
#include "ephy-embed-find.h"
#include "ephy-embed-shell.h"
-#include "ephy-object-helpers.h"
#include "ephy-debug.h"
#define MOZILLA_EMBED_FIND_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), MOZILLA_TYPE_EMBED_FIND, MozillaEmbedFindPrivate))
@@ -122,7 +121,7 @@ mozilla_embed_find_finalize (GObject *object)
parent_class->finalize (object);
- ephy_object_idle_unref (embed_shell);
+ g_object_unref (embed_shell);
}
static void
diff --git a/embed/mozilla/mozilla-embed-single.cpp b/embed/mozilla/mozilla-embed-single.cpp
index 2053914e9..00d06875a 100644
--- a/embed/mozilla/mozilla-embed-single.cpp
+++ b/embed/mozilla/mozilla-embed-single.cpp
@@ -28,6 +28,7 @@
#include "ephy-cookie-manager.h"
#include "ephy-password-manager.h"
#include "ephy-permission-manager.h"
+#include "ephy-embed-shell.h"
#include "glib.h"
#include "ephy-debug.h"
@@ -545,6 +546,20 @@ init_services (MozillaEmbedSingle *single)
}
static void
+prepare_close_cb (EphyEmbedShell *shell)
+{
+ GValue value = { 0, };
+
+ /* To avoid evil web sites posing an alert and thus inhibiting
+ * shutdown, we just turn off javascript! :)
+ */
+ g_value_init (&value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&value, FALSE);
+ mozilla_pref_set ("javascript.enabled", &value);
+ g_value_unset (&value);
+}
+
+static void
mozilla_embed_single_init (MozillaEmbedSingle *mes)
{
mes->priv = MOZILLA_EMBED_SINGLE_GET_PRIVATE (mes);
@@ -571,6 +586,10 @@ mozilla_embed_single_init (MozillaEmbedSingle *mes)
exit (0);
}
+
+ g_signal_connect_object (embed_shell, "prepare-close",
+ G_CALLBACK (prepare_close_cb), mes,
+ (GConnectFlags) 0);
}
static void
diff --git a/embed/mozilla/mozilla-embed.cpp b/embed/mozilla/mozilla-embed.cpp
index 1b7733e0d..1a8e31b55 100644
--- a/embed/mozilla/mozilla-embed.cpp
+++ b/embed/mozilla/mozilla-embed.cpp
@@ -29,7 +29,6 @@
#include "ephy-embed-shell.h"
#include "ephy-command-manager.h"
#include "ephy-string.h"
-#include "ephy-object-helpers.h"
#include "ephy-debug.h"
#include "EphyBrowser.h"
@@ -293,7 +292,7 @@ mozilla_embed_finalize (GObject *object)
G_OBJECT_CLASS (parent_class)->finalize (object);
- ephy_object_idle_unref (embed_shell);
+ g_object_unref (embed_shell);
}
static void
@@ -1135,6 +1134,13 @@ _mozilla_embed_new_xul_dialog (void)
g_object_ref (embed_shell);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_object_set_data_full (G_OBJECT (window), "EmbedShellRef",
+ embed_shell,
+ (GDestroyNotify) g_object_unref);
+ g_signal_connect_object (embed_shell, "prepare_close",
+ G_CALLBACK (gtk_widget_destroy), window,
+ (GConnectFlags) G_CONNECT_SWAPPED);
+
embed = gtk_moz_embed_new ();
gtk_widget_show (embed);
gtk_container_add (GTK_CONTAINER (window), embed);
@@ -1155,8 +1161,5 @@ _mozilla_embed_new_xul_dialog (void)
G_CALLBACK (xul_title_cb),
window, (GConnectFlags) 0);
- g_object_weak_ref (G_OBJECT (window),
- (GWeakNotify) ephy_object_idle_unref, embed_shell);
-
return GTK_MOZ_EMBED (embed);
}
diff --git a/embed/mozilla/mozilla-notifiers.cpp b/embed/mozilla/mozilla-notifiers.cpp
index 717a4fcbc..db227962b 100644
--- a/embed/mozilla/mozilla-notifiers.cpp
+++ b/embed/mozilla/mozilla-notifiers.cpp
@@ -412,8 +412,8 @@ static const PrefData notifier_entries[] =
transform_cookies_accept_mode },
};
-static gboolean
-mozilla_set_pref (const char *pref,
+gboolean
+mozilla_pref_set (const char *pref,
const GValue *value)
{
g_return_val_if_fail (pref != NULL, FALSE);
@@ -466,7 +466,7 @@ notify_cb (GConfClient *client,
if (data->func (gcvalue, &value, data->user_data))
{
- mozilla_set_pref (data->mozilla_pref, &value);
+ mozilla_pref_set (data->mozilla_pref, &value);
g_value_unset (&value);
}
}
diff --git a/embed/mozilla/mozilla-notifiers.h b/embed/mozilla/mozilla-notifiers.h
index 72d5d1cf4..642361c29 100644
--- a/embed/mozilla/mozilla-notifiers.h
+++ b/embed/mozilla/mozilla-notifiers.h
@@ -45,6 +45,9 @@ guint mozilla_notifier_add (const char *gconf_key,
void mozilla_notifier_remove (guint id);
+gboolean mozilla_pref_set (const char *pref,
+ const GValue *value);
+
void mozilla_notifiers_init (void);
void mozilla_notifiers_shutdown (void);
diff --git a/src/ephy-session.c b/src/ephy-session.c
index 96e016137..f39001116 100644
--- a/src/ephy-session.c
+++ b/src/ephy-session.c
@@ -57,7 +57,8 @@ struct _EphySessionPrivate
GList *windows;
GList *tool_windows;
GtkWidget *resume_dialog;
- gboolean dont_save;
+ guint dont_save : 1;
+ guint quit_while_resuming : 1;
};
#define BOOKMARKS_EDITOR_ID "BookmarksEditor"
@@ -262,40 +263,28 @@ impl_detach_window (EphyExtension *extension,
}
static void
-ensure_session_directory (void)
-{
- char *dir;
-
- dir = g_build_filename (ephy_dot_dir (), "sessions", NULL);
- if (g_file_test (dir, G_FILE_TEST_EXISTS) == FALSE)
- {
- if (mkdir (dir, 488) != 0)
- {
- g_error ("Unable to create session directory '%s'\n", dir);
- }
- }
-
- g_free (dir);
-}
-
-static void
ephy_session_init (EphySession *session)
{
session->priv = EPHY_SESSION_GET_PRIVATE (session);
LOG ("EphySession initialising");
-
- ensure_session_directory ();
}
static void
ephy_session_dispose (GObject *object)
{
EphySession *session = EPHY_SESSION(object);
+ EphySessionPrivate *priv = session->priv;
LOG ("EphySession disposing");
- session_delete (session, SESSION_CRASHED);
+ /* Only remove the crashed session if we're not shutting down while
+ * the session resume dialogue was still shown!
+ */
+ if (priv->quit_while_resuming == FALSE)
+ {
+ session_delete (session, SESSION_CRASHED);
+ }
parent_class->dispose (object);
}
@@ -462,12 +451,25 @@ ephy_session_autoresume (EphySession *session,
g_free (saved_session);
- return retval;
+ /* ensure we don't open a blank window when quitting while resuming */
+ return retval || priv->quit_while_resuming;
+}
+
+static void
+close_dialog (GtkWidget *widget)
+{
+ if (GTK_IS_DIALOG (widget))
+ {
+ /* don't destroy them, someone might have a ref on them */
+ gtk_dialog_response (GTK_DIALOG (widget),
+ GTK_RESPONSE_DELETE_EVENT);
+ }
}
void
ephy_session_close (EphySession *session)
{
+ EphySessionPrivate *priv = session->priv;
GList *windows;
LOG ("ephy_session_close");
@@ -476,7 +478,12 @@ ephy_session_close (EphySession *session)
* destroying the windows and destroying the tool windows
*/
g_object_ref (ephy_shell);
- session->priv->dont_save = TRUE;
+
+ priv->dont_save = TRUE;
+ /* need to set this up here while the dialogue hasn't been killed yet */
+ priv->quit_while_resuming = priv->resume_dialog != NULL;
+
+ ephy_embed_shell_prepare_close (embed_shell);
windows = ephy_session_get_windows (session);
g_list_foreach (windows, (GFunc) gtk_widget_destroy, NULL);
@@ -486,6 +493,17 @@ ephy_session_close (EphySession *session)
g_list_foreach (windows, (GFunc) gtk_widget_destroy, NULL);
g_list_free (windows);
+ ephy_embed_shell_prepare_close (embed_shell);
+
+ /* there may still be windows open, like dialogues posed from
+ * web pages, etc. Try to kill them, but be sure NOT to destroy
+ * the gtkmozembed offscreen window!
+ * Here, we just check if it's a dialogue and close it if it is one.
+ */
+ windows = gtk_window_list_toplevels ();
+ g_list_foreach (windows, (GFunc) close_dialog, NULL);
+ g_list_free (windows);
+
session->priv->dont_save = FALSE;
g_object_unref (ephy_shell);
}
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index 4b9bd1993..26eb28a61 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -47,7 +47,6 @@
#include "print-dialog.h"
#include "ephy-prefs.h"
#include "ephy-gui.h"
-#include "ephy-object-helpers.h"
#ifdef ENABLE_DBUS
#include "ephy-dbus.h"
@@ -481,8 +480,13 @@ ephy_shell_startup (EphyShell *shell,
"from Bonobo when attempting to locate the automation "
"object."));
automation = NULL;
+ goto done;
}
- else if (flags & EPHY_SHELL_STARTUP_BOOKMARKS_EDITOR)
+
+ /* init the session manager up here so we can quit while the resume dialogue is on */
+ gnome_session_init (shell);
+
+ if (flags & EPHY_SHELL_STARTUP_BOOKMARKS_EDITOR)
{
GNOME_EphyAutomation_openBookmarksEditorWithStartupId
(automation, user_time, &ev);
@@ -510,14 +514,10 @@ ephy_shell_startup (EphyShell *shell,
flags & EPHY_SHELL_STARTUP_FULLSCREEN);
}
- if (automation)
- {
- bonobo_object_release_unref (automation, &ev);
- }
-
- gnome_session_init (shell);
+ bonobo_object_release_unref (automation, &ev);
}
+done:
CORBA_exception_free (&ev);
gdk_notify_startup_complete ();
@@ -941,8 +941,7 @@ toolwindow_hide_cb (GtkWidget *widget, EphyShell *es)
session = EPHY_SESSION (ephy_shell_get_session (es));
ephy_session_remove_window (ephy_shell->priv->session, GTK_WINDOW (widget));
-
- ephy_object_idle_unref (ephy_shell);
+ g_object_unref (ephy_shell);
}
GtkWidget *
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 186458fbd..3269b9c1b 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -56,7 +56,6 @@
#include "ephy-fullscreen-popup.h"
#include "ephy-action-helper.h"
#include "ephy-find-toolbar.h"
-#include "ephy-object-helpers.h"
#include <string.h>
#include <glib/gi18n.h>
@@ -2858,7 +2857,7 @@ ephy_window_finalize (GObject *object)
LOG ("Ephy Window finalized %p", object);
- ephy_object_idle_unref (ephy_shell);
+ g_object_unref (ephy_shell);
}
/**