aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ephy-activation.c119
-rw-r--r--src/ephy-activation.h2
-rw-r--r--src/ephy-dbus.c5
-rw-r--r--src/ephy-dbus.h5
-rw-r--r--src/ephy-main.c264
-rw-r--r--src/ephy-session.c622
-rw-r--r--src/ephy-session.h25
-rw-r--r--src/epiphany.defs9
8 files changed, 689 insertions, 362 deletions
diff --git a/src/ephy-activation.c b/src/ephy-activation.c
index 8ad478748..c5b01d386 100644
--- a/src/ephy-activation.c
+++ b/src/ephy-activation.c
@@ -25,108 +25,57 @@
#include "ephy-shell.h"
#include "ephy-session.h"
#include "ephy-prefs.h"
-#include "ephy-gui.h"
#include "eel-gconf-extensions.h"
#include "ephy-debug.h"
-#include <string.h>
-
-gboolean
-ephy_activation_load_uris (EphyDbus *ephy_dbus,
- char **uris,
- char *options,
- guint startup_id,
- GError **error)
+static gboolean
+session_queue_command (EphySessionCommand command,
+ char *arg,
+ char **args,
+ guint startup_id,
+ GError **error)
{
EphyShell *shell;
EphySession *session;
- EphyNewTabFlags flags = 0;
- EphyWindow *window;
- EphyTab *tab;
- static char *empty_urls[] = { "", NULL };
- guint32 user_time = (guint32) startup_id;
- guint i;
-
- g_return_val_if_fail (uris != NULL && options != NULL, TRUE);
shell = ephy_shell_get_default ();
-
- g_object_ref (shell);
-
- session = EPHY_SESSION (ephy_shell_get_session (shell));
- g_assert (session != NULL);
-
- if (eel_gconf_get_boolean (CONF_LOCKDOWN_DISABLE_ARBITRARY_URL))
- {
- uris = empty_urls;
- }
-
- window = ephy_session_get_active_window (session);
-
-#if 0
- if (open_in_existing_tab && window != NULL)
- {
- ephy_gui_window_update_user_time (GTK_WIDGET (window),
- user_time);
- ephy_window_load_url (window, url);
- return TRUE;
- }
-#endif
-
- if (strstr (options, "new-window") != NULL)
- {
- window = NULL;
- flags |= EPHY_NEW_TAB_IN_NEW_WINDOW;
- }
- else if (strstr (options, "new-tab") != NULL)
- {
- flags |= EPHY_NEW_TAB_IN_EXISTING_WINDOW |
- EPHY_NEW_TAB_JUMP;
- }
-
- for (i = 0; uris[i] != NULL; ++i)
+ if (shell == NULL)
{
- const char *url = uris[i];
- EphyNewTabFlags page_flags;
-
- if (url[0] == '\0')
- {
- page_flags = EPHY_NEW_TAB_HOME_PAGE;
- }
- else
- {
- page_flags = EPHY_NEW_TAB_OPEN_PAGE;
- }
-
- tab = ephy_shell_new_tab_full (shell,window,
- NULL, url,
- flags | page_flags,
- EPHY_EMBED_CHROME_ALL,
- FALSE, user_time);
-
- window = EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab)));
+ g_set_error (error,
+ g_quark_from_static_string ("ephy-activation-error"),
+ 0,
+ "Shutting down." /* FIXME i18n & better string */);
+ return FALSE;
}
- g_object_unref (shell);
+ session = EPHY_SESSION (ephy_shell_get_session (ephy_shell_get_default()));
+ g_assert (session != NULL);
- /* FIXME: do we have to g_strfreev (uris) ? */
+ ephy_session_queue_command (session, command, arg, args,
+ (guint32) startup_id, FALSE);
return TRUE;
}
gboolean
+ephy_activation_load_uri_list (EphyDbus *ephy_dbus,
+ char **uris,
+ char *options,
+ guint startup_id,
+ GError **error)
+{
+ return session_queue_command (EPHY_SESSION_CMD_OPEN_URIS,
+ options, uris, startup_id, error);
+}
+
+gboolean
ephy_activation_load_session (EphyDbus *ephy_dbus,
char *session_name,
guint startup_id,
GError **error)
{
- EphySession *session;
- guint32 user_time = (guint32) startup_id;
-
- session = EPHY_SESSION (ephy_shell_get_session (ephy_shell));
- ephy_session_load (session, session_name, user_time);
-
- return TRUE;
+ return session_queue_command (EPHY_SESSION_CMD_LOAD_SESSION,
+ session_name, NULL, startup_id, error);
}
gboolean
@@ -134,9 +83,6 @@ ephy_activation_open_bookmarks_editor (EphyDbus *ephy_dbus,
guint startup_id,
GError **error)
{
- GtkWidget *editor;
- guint32 user_time = (guint32) startup_id;
-
if (eel_gconf_get_boolean (CONF_LOCKDOWN_DISABLE_BOOKMARK_EDITING))
{
g_set_error (error,
@@ -147,9 +93,6 @@ ephy_activation_open_bookmarks_editor (EphyDbus *ephy_dbus,
return FALSE;
}
- editor = ephy_shell_get_bookmarks_editor (ephy_shell);
- ephy_gui_window_update_user_time (editor, user_time);
- gtk_window_present (GTK_WINDOW (editor));
-
- return TRUE;
+ return session_queue_command (EPHY_SESSION_CMD_OPEN_BOOKMARKS_EDITOR,
+ NULL, NULL, startup_id, error);
}
diff --git a/src/ephy-activation.h b/src/ephy-activation.h
index 600759329..daf62d59f 100644
--- a/src/ephy-activation.h
+++ b/src/ephy-activation.h
@@ -26,7 +26,7 @@
G_BEGIN_DECLS
/* activation handlers */
-gboolean ephy_activation_load_uris (EphyDbus *ephy_dbus,
+gboolean ephy_activation_load_uri_list (EphyDbus *ephy_dbus,
char **uris,
char *options,
guint startup_id,
diff --git a/src/ephy-dbus.c b/src/ephy-dbus.c
index 197fea900..e43523596 100644
--- a/src/ephy-dbus.c
+++ b/src/ephy-dbus.c
@@ -41,6 +41,11 @@
#define DBUS_NAME_FLAG_DO_NOT_QUEUE 0
#endif
+/* Epiphany's DBUS ids */
+#define DBUS_EPHY_SERVICE "org.gnome.Epiphany"
+#define DBUS_EPHY_PATH "/org/gnome/Epiphany"
+#define DBUS_EPHY_INTERFACE "org.gnome.Epiphany"
+
#define RECONNECT_DELAY 3000
#define EPHY_DBUS_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_DBUS, EphyDbusPrivate))
diff --git a/src/ephy-dbus.h b/src/ephy-dbus.h
index 611be0b77..943a44c76 100644
--- a/src/ephy-dbus.h
+++ b/src/ephy-dbus.h
@@ -30,11 +30,6 @@
G_BEGIN_DECLS
-/* Epiphany's DBUS ids */
-#define DBUS_EPHY_SERVICE "org.gnome.Epiphany"
-#define DBUS_EPHY_PATH "/org/gnome/Epiphany"
-#define DBUS_EPHY_INTERFACE "org.gnome.Epiphany"
-
#define EPHY_TYPE_DBUS (ephy_dbus_get_type ())
#define EPHY_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_DBUS, EphyDbus))
#define EPHY_DBUS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_DBUS, EphyDbusClass))
diff --git a/src/ephy-main.c b/src/ephy-main.c
index be5954587..af53d230b 100644
--- a/src/ephy-main.c
+++ b/src/ephy-main.c
@@ -32,6 +32,7 @@
#include "ephy-activation.h"
#include "ephy-session.h"
#include "ephy-shell.h"
+#include "ephy-prefs.h"
#include "ephy-debug.h"
#include <libxml/xmlversion.h>
@@ -44,7 +45,6 @@
#include <gtk/gtkmessagedialog.h>
#include <libgnome/gnome-program.h>
-#include <libgnomeui/gnome-client.h>
#include <libgnomeui/gnome-ui-init.h>
#include <libgnomevfs/gnome-vfs-init.h>
@@ -111,10 +111,17 @@ static const GOptionEntry libgnome_option_entries[] =
#endif /* !GNOME_PARAM_GOPTION_CONTEXT */
#ifdef GNOME_ENABLE_DEBUG
+static gboolean keep_profile_directory = FALSE;
+static char *profile_directory = NULL;
+
static GOptionEntry debug_option_entries[] =
{
{ "private-instance", 0, 0, G_OPTION_ARG_NONE, &private_instance,
- N_("Start a private instance"), NULL },
+ "Start a private instance", NULL },
+ { "profile", 'p', 0, G_OPTION_ARG_STRING, &profile_directory,
+ "Profile directory to use in the private instance (default: a newly created directory in tmpdir)", "DIR" },
+ { "keep-profile", 0, 0, G_OPTION_ARG_NONE, &keep_profile_directory,
+ "Don't delete the profile directory on exit (default: delete the temp profile on exit)", NULL },
{ NULL }
};
#endif /* GNOME_ENABLE_DEBUG */
@@ -235,100 +242,6 @@ shell_weak_notify (gpointer data,
}
}
-static void
-dbus_g_proxy_finalized_cb (EphyShell *shell,
- GObject *zombie)
-{
- LOG ("dbus_g_proxy_finalized_cb");
-
- g_object_unref (shell);
-}
-
-/* Gnome session client */
-
-static gboolean
-save_yourself_cb (GnomeClient *client,
- gint phase,
- GnomeSaveStyle save_style,
- gboolean shutdown,
- GnomeInteractStyle interact_style,
- gboolean fast,
- gpointer user_data)
-{
- EphyShell *shell;
- EphySession *session;
- char *argv[] = { NULL, "--load-session", NULL };
- char *discard_argv[] = { "rm", "-f", NULL };
- char *tmp, *save_to;
-
- LOG ("save_yourself_cb");
-
- /* FIXME FIXME */
- if (!ephy_shell_get_default ()) return FALSE;
-
- tmp = g_build_filename (ephy_dot_dir (),
- "session_gnome-XXXXXX",
- NULL);
- save_to = ephy_file_tmp_filename (tmp, "xml");
- g_free (tmp);
-
- shell = ephy_shell_get_default ();
- g_assert (shell != NULL);
-
- session = EPHY_SESSION (ephy_shell_get_session (shell));
- g_assert (session != NULL);
-
- argv[0] = g_get_prgname ();
- argv[2] = save_to;
- gnome_client_set_restart_command
- (client, 3, argv);
-
- discard_argv[2] = save_to;
- gnome_client_set_discard_command (client, 3,
- discard_argv);
-
- ephy_session_save (session, save_to);
-
- g_free (save_to);
-
- return TRUE;
-}
-
-static void
-die_cb (GnomeClient* client,
- gpointer user_data)
-
-{
- EphyShell *shell;
- EphySession *session;
-
- LOG ("die_cb");
-
- /* FIXME FIXME */
- if (!ephy_shell_get_default ()) return;
-
- shell = ephy_shell_get_default ();
- g_assert (shell != NULL);
-
- session = EPHY_SESSION (ephy_shell_get_session (shell));
- g_assert (session != NULL);
-
- ephy_session_close (session);
-}
-
-static void
-gnome_session_init (void)
-{
- GnomeClient *client;
-
- client = gnome_master_client ();
-
- g_signal_connect (client, "save_yourself",
- G_CALLBACK (save_yourself_cb), NULL);
- g_signal_connect (client, "die",
- G_CALLBACK (die_cb), NULL);
-}
-
#if 0
static char *
path_from_command_line_arg (const char *arg)
@@ -359,7 +272,7 @@ unref_proxy_reply_cb (DBusGProxy *proxy,
g_object_unref (proxy);
- if (!_ephy_dbus_is_name_owner () && gtk_main_level ())
+ if (gtk_main_level ())
{
gtk_main_quit ();
}
@@ -372,6 +285,7 @@ open_urls (DBusGProxy *proxy,
{
static const char *empty_arguments[] = { "", NULL };
GString *options;
+ char **uris;
options = g_string_sized_new (64);
@@ -384,13 +298,20 @@ open_urls (DBusGProxy *proxy,
g_string_append (options, "new-tab,");
}
- org_gnome_Epiphany_load_uris_async
- (proxy,
- extra_arguments ? (const char**) extra_arguments : (const char**)empty_arguments,
- options->str, user_time,
+ if (extra_arguments == NULL)
+ {
+ uris = (char **) empty_arguments;
+ }
+ else
+ {
+ uris = (char **) extra_arguments;
+ }
+
+ org_gnome_Epiphany_load_ur_ilist_async
+ (proxy, (const char **) uris, options->str, user_time,
unref_proxy_reply_cb, NULL);
- if (extra_arguments)
+ if (extra_arguments != NULL)
{
g_strfreev (extra_arguments);
extra_arguments = NULL;
@@ -422,22 +343,13 @@ call_dbus_proxy (DBusGProxy *proxy,
org_gnome_Epiphany_load_session_async
(proxy, session_filename, user_time,
unref_proxy_reply_cb, shell);
+
+ g_free (session_filename);
+ session_filename = NULL;
}
else
{
- /* no need to open the homepage if autoresume returns TRUE;
- * we already opened session windows */
- if (!_ephy_dbus_is_name_owner () ||
- (ephy_session_autoresume
- (EPHY_SESSION (ephy_shell_get_session (shell)),
- user_time) == FALSE))
- {
- retval = open_urls (proxy, user_time, error);
- }
- else
- {
- ephy_object_idle_unref (proxy);
- }
+ retval = open_urls (proxy, user_time, error);
}
/* FIXME why? */
@@ -447,6 +359,70 @@ call_dbus_proxy (DBusGProxy *proxy,
}
static void
+queue_commands (guint32 user_time)
+{
+ EphyShell *shell;
+ EphySession *session;
+
+ shell = ephy_shell_get_default ();
+ g_assert (shell != NULL);
+
+ session = EPHY_SESSION (ephy_shell_get_session (shell));
+ g_assert (session != NULL);
+
+ /* We only get here when starting a new instance, so we
+ * first need to autoresume!
+ */
+ ephy_session_queue_command (session,
+ EPHY_SESSION_CMD_RESUME_SESSION,
+ NULL, NULL, user_time, TRUE);
+
+ if (open_as_bookmarks_editor)
+ {
+ ephy_session_queue_command (session,
+ EPHY_SESSION_CMD_OPEN_BOOKMARKS_EDITOR,
+ NULL, NULL, user_time, FALSE);
+ }
+ else if (session_filename != NULL)
+ {
+ ephy_session_queue_command (session,
+ EPHY_SESSION_CMD_LOAD_SESSION,
+ session_filename, NULL,
+ user_time, FALSE);
+
+ g_free (session_filename);
+ session_filename = NULL;
+ }
+ /* Don't queue any window openings if no extra arguments given,
+ * since session autoresume will open one for us.
+ */
+ else if (extra_arguments != NULL)
+ {
+ GString *options;
+
+ options = g_string_sized_new (64);
+
+ if (open_in_new_window)
+ {
+ g_string_append (options, "new-window,");
+ }
+ if (open_in_new_tab)
+ {
+ g_string_append (options, "new-tab,");
+ }
+
+ ephy_session_queue_command (session,
+ EPHY_SESSION_CMD_OPEN_URIS,
+ options->str,
+ extra_arguments,
+ user_time, FALSE);
+
+ g_strfreev (extra_arguments);
+ extra_arguments = NULL;
+ }
+}
+
+static void
show_error_message (GError **error)
{
GtkWidget *dialog;
@@ -582,6 +558,12 @@ main (int argc,
#endif /* GNOME_PARAM_GOPTION_CONTEXT */
+ if (extra_arguments != NULL &&
+ eel_gconf_get_boolean (CONF_LOCKDOWN_DISABLE_ARBITRARY_URL))
+ {
+ exit (1);
+ }
+
/* Get a timestamp manually if need be */
if (user_time == 0)
{
@@ -605,26 +587,26 @@ main (int argc,
exit (1);
}
- /* Create DBUS proxy */
- proxy = ephy_dbus_get_proxy (ephy_dbus_get_default (), EPHY_DBUS_SESSION);
- if (proxy == NULL)
- {
- error = g_error_new (STARTUP_ERROR_QUARK,
- 0,
- "Unable to get DBus proxy; aborting activation."); /* FIXME i18n */
-
- _ephy_dbus_release ();
-
- show_error_message (&error);
-
- exit (1);
- }
-
/* If we're remoting, no need to start up any further services,
* just forward the call.
*/
if (!_ephy_dbus_is_name_owner ())
{
+ /* Create DBUS proxy */
+ proxy = ephy_dbus_get_proxy (ephy_dbus_get_default (), EPHY_DBUS_SESSION);
+ if (proxy == NULL)
+ {
+ error = g_error_new (STARTUP_ERROR_QUARK,
+ 0,
+ "Unable to get DBus proxy; aborting activation."); /* FIXME i18n */
+
+ _ephy_dbus_release ();
+
+ show_error_message (&error);
+
+ exit (1);
+ }
+
if (!call_dbus_proxy (proxy, user_time, &error))
{
_ephy_dbus_release ();
@@ -645,7 +627,7 @@ main (int argc,
/* We're not remoting; start our services */
- if (!ephy_file_helpers_init (FALSE, &error))
+ if (!ephy_file_helpers_init (NULL, FALSE, FALSE, &error))
{
_ephy_dbus_release ();
@@ -654,9 +636,6 @@ main (int argc,
exit (1);
}
- /* init the session manager up here so we can quit while the resume dialogue is shown */
- gnome_session_init ();
-
eel_gconf_monitor_add ("/apps/epiphany/general");
gnome_vfs_init ();
ephy_stock_icons_init ();
@@ -676,23 +655,8 @@ main (int argc,
/* Now create the shell */
_ephy_shell_create_instance ();
- g_object_weak_ref (G_OBJECT (proxy),
- (GWeakNotify) dbus_g_proxy_finalized_cb,
- g_object_ref (ephy_shell_get_default ()));
- if (!call_dbus_proxy (proxy, user_time, &error))
- {
- g_object_unref (ephy_shell_get_default ());
- g_object_unref (proxy);
- g_assert (ephy_shell_get_default () == NULL);
-
- ephy_file_helpers_shutdown ();
- _ephy_dbus_release ();
-
- show_error_message (&error);
-
- exit (1);
- }
+ queue_commands (user_time);
/* We'll release the initial reference on idle */
g_object_weak_ref (G_OBJECT (ephy_shell), shell_weak_notify, NULL);
diff --git a/src/ephy-session.c b/src/ephy-session.c
index ffa81bbe6..d9a9a59a0 100644
--- a/src/ephy-session.c
+++ b/src/ephy-session.c
@@ -36,9 +36,7 @@
#include "ephy-debug.h"
#include <glib/gi18n.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
+#include <gtk/gtkmain.h>
#include <gtk/gtkimage.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkstock.h>
@@ -46,11 +44,27 @@
#include <gtk/gtkvbox.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtkmessagedialog.h>
+
+#include <libgnomeui/gnome-client.h>
+
#include <libgnomevfs/gnome-vfs-ops.h>
#include <libgnomevfs/gnome-vfs-utils.h>
+
#include <libxml/tree.h>
#include <libxml/xmlwriter.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+typedef struct
+{
+ EphySessionCommand command;
+ char *arg;
+ char **args;
+ guint32 user_time;
+} SessionCommand;
+
#define EPHY_SESSION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_SESSION, EphySessionPrivate))
struct _EphySessionPrivate
@@ -58,6 +72,10 @@ struct _EphySessionPrivate
GList *windows;
GList *tool_windows;
GtkWidget *resume_dialog;
+
+ GQueue *queue;
+ guint queue_idle_id;
+
guint dont_save : 1;
guint quit_while_resuming : 1;
};
@@ -69,6 +87,7 @@ struct _EphySessionPrivate
static void ephy_session_class_init (EphySessionClass *klass);
static void ephy_session_iface_init (EphyExtensionIface *iface);
static void ephy_session_init (EphySession *session);
+static void session_command_queue_next (EphySession *session);
enum
{
@@ -117,6 +136,57 @@ ephy_session_get_type (void)
return type;
}
+/* Gnome session client */
+
+static gboolean
+save_yourself_cb (GnomeClient *client,
+ gint phase,
+ GnomeSaveStyle save_style,
+ gboolean shutdown,
+ GnomeInteractStyle interact_style,
+ gboolean fast,
+ EphySession *session)
+{
+ char *argv[] = { NULL, "--load-session", NULL };
+ char *discard_argv[] = { "rm", "-f", NULL };
+ char *tmp, *save_to;
+
+ LOG ("save_yourself_cb");
+
+ tmp = g_build_filename (ephy_dot_dir (),
+ "session_gnome-XXXXXX",
+ NULL);
+ save_to = ephy_file_tmp_filename (tmp, "xml");
+ g_free (tmp);
+
+ argv[0] = g_get_prgname ();
+ argv[2] = save_to;
+ gnome_client_set_restart_command
+ (client, 3, argv);
+
+ discard_argv[2] = save_to;
+ gnome_client_set_discard_command (client, 3,
+ discard_argv);
+
+ ephy_session_save (session, save_to);
+
+ g_free (save_to);
+
+ return TRUE;
+}
+
+static void
+die_cb (GnomeClient* client,
+ EphySession *session)
+
+{
+ LOG ("die_cb");
+
+ ephy_session_close (session);
+}
+
+/* Helper functions */
+
static char *
get_session_filename (const char *filename)
{
@@ -207,6 +277,334 @@ window_focus_in_event_cb (EphyWindow *window,
return FALSE;
}
+/* Queue worker */
+
+static void
+session_command_free (SessionCommand *cmd)
+{
+ g_assert (cmd != NULL);
+
+ g_free (cmd->arg);
+ if (cmd->args)
+ {
+ g_strfreev (cmd->args);
+ }
+
+ g_free (cmd);
+
+ g_object_unref (ephy_shell_get_default ());
+}
+
+static int
+session_command_find (const SessionCommand *cmd,
+ gpointer cmdptr)
+{
+ EphySessionCommand command = GPOINTER_TO_INT (cmdptr);
+
+ return command != cmd->command;
+}
+
+static void
+resume_dialog_response_cb (GtkWidget *dialog,
+ int response,
+ EphySession *session)
+{
+ guint32 user_time;
+
+ LOG ("resume_dialog_response_cb response:%d", response);
+
+ gtk_widget_hide (dialog);
+
+ user_time = gtk_get_current_event_time ();
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ {
+ ephy_session_queue_command (session,
+ EPHY_SESSION_CMD_LOAD_SESSION,
+ SESSION_CRASHED, NULL,
+ user_time, TRUE);
+ }
+
+ ephy_session_queue_command (session,
+ EPHY_SESSION_CMD_MAYBE_OPEN_WINDOW,
+ NULL, NULL, user_time, FALSE);
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+resume_dialog_weak_ref_cb (EphySession *session,
+ GObject *zombie)
+{
+ EphySessionPrivate *priv = session->priv;
+
+ LOG ("resume_dialog_weak_ref_cb");
+
+ priv->resume_dialog = NULL;
+
+ gtk_window_set_auto_startup_notification (TRUE);
+
+ session_command_queue_next (session);
+
+ g_object_unref (ephy_shell_get_default ());
+}
+
+static void
+session_command_autoresume (EphySession *session,
+ guint32 user_time)
+{
+ EphySessionPrivate *priv = session->priv;
+ GtkWidget *dialog;
+ char *saved_session;
+ gboolean crashed_session;
+
+ LOG ("ephy_session_autoresume");
+
+ saved_session = get_session_filename (SESSION_CRASHED);
+ crashed_session = g_file_test (saved_session, G_FILE_TEST_EXISTS);
+ g_free (saved_session);
+
+ if (crashed_session == FALSE ||
+ priv->windows != NULL ||
+ priv->tool_windows != NULL)
+ {
+ /* FIXME can this happen? */
+ if (priv->resume_dialog != NULL)
+ {
+ gtk_widget_hide (priv->resume_dialog);
+ gtk_widget_destroy (priv->resume_dialog);
+ }
+
+ ephy_session_queue_command (session,
+ EPHY_SESSION_CMD_MAYBE_OPEN_WINDOW,
+ NULL, NULL, user_time, FALSE);
+
+ return;
+ }
+
+ if (priv->resume_dialog)
+ {
+ gtk_window_present_with_time (GTK_WINDOW (priv->resume_dialog),
+ user_time);
+
+ return;
+ }
+
+ /* Ref the shell while we show the dialogue. The unref
+ * happens in the weak ref notification when the dialogue
+ * is destroyed.
+ */
+ g_object_ref (ephy_shell_get_default ());
+
+ dialog = gtk_message_dialog_new
+ (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ _("Recover previous browser windows and tabs?"));
+
+ gtk_message_dialog_format_secondary_text
+ (GTK_MESSAGE_DIALOG (dialog),
+ _("Epiphany appears to have exited unexpectedly the last time "
+ "it was run. You can recover the opened windows and tabs."));
+
+ gtk_dialog_add_button (GTK_DIALOG (dialog),
+ _("_Don't Recover"), GTK_RESPONSE_CANCEL);
+ gtk_dialog_add_button (GTK_DIALOG (dialog),
+ _("_Recover"), GTK_RESPONSE_ACCEPT);
+
+ gtk_window_set_title (GTK_WINDOW (dialog), _("Crash Recovery"));
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "web-browser");
+ gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+
+ g_signal_connect (dialog, "response",
+ G_CALLBACK (resume_dialog_response_cb), session);
+ g_object_weak_ref (G_OBJECT (dialog),
+ (GWeakNotify) resume_dialog_weak_ref_cb,
+ session);
+
+ /* FIXME ? */
+ gtk_window_set_auto_startup_notification (FALSE);
+
+ priv->resume_dialog = dialog;
+
+ gtk_window_present_with_time (GTK_WINDOW (dialog), user_time);
+}
+
+static void
+session_command_open_bookmarks_editor (EphySession *session,
+ guint32 user_time)
+{
+ GtkWidget *editor;
+
+ editor = ephy_shell_get_bookmarks_editor (ephy_shell_get_default ());
+
+ gtk_window_present_with_time (GTK_WINDOW (editor), user_time);
+}
+
+static void
+session_command_open_uris (EphySession *session,
+ char **uris,
+ const char *options,
+ guint32 user_time)
+{
+ EphyShell *shell;
+ EphyWindow *window;
+ EphyTab *tab;
+ EphyNewTabFlags flags = 0;
+ guint i;
+
+ shell = ephy_shell_get_default ();
+
+ g_object_ref (shell);
+
+ window = ephy_session_get_active_window (session);
+
+ if (options != NULL && strstr (options, "new-window") != NULL)
+ {
+ window = NULL;
+ flags |= EPHY_NEW_TAB_IN_NEW_WINDOW;
+ }
+ else if (options != NULL && strstr (options, "new-tab") != NULL)
+ {
+ flags |= EPHY_NEW_TAB_IN_EXISTING_WINDOW |
+ EPHY_NEW_TAB_JUMP;
+ }
+
+ for (i = 0; uris[i] != NULL; ++i)
+ {
+ const char *url = uris[i];
+ EphyNewTabFlags page_flags;
+
+ if (url[0] == '\0')
+ {
+ page_flags = EPHY_NEW_TAB_HOME_PAGE;
+ }
+ else
+ {
+ page_flags = EPHY_NEW_TAB_OPEN_PAGE;
+ }
+
+ tab = ephy_shell_new_tab_full (shell, window,
+ NULL /* parent tab */,
+ url,
+ flags | page_flags,
+ EPHY_EMBED_CHROME_ALL,
+ FALSE /* is popup? */,
+ user_time);
+
+ window = EPHY_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (tab)));
+ }
+
+ g_object_unref (shell);
+}
+
+static gboolean
+session_command_dispatch (EphySession *session)
+{
+ EphySessionPrivate *priv = session->priv;
+ SessionCommand *cmd;
+ gboolean run_again = TRUE;
+
+ cmd = g_queue_pop_head (priv->queue);
+ g_assert (cmd != NULL);
+
+ LOG ("dispatching queue cmd:%d", cmd->command);
+
+ switch (cmd->command)
+ {
+ case EPHY_SESSION_CMD_RESUME_SESSION:
+ session_command_autoresume (session, cmd->user_time);
+ break;
+ case EPHY_SESSION_CMD_LOAD_SESSION:
+ ephy_session_load (session, cmd->arg, cmd->user_time);
+ break;
+ case EPHY_SESSION_CMD_OPEN_BOOKMARKS_EDITOR:
+ session_command_open_bookmarks_editor (session, cmd->user_time);
+ break;
+ case EPHY_SESSION_CMD_OPEN_URIS:
+ session_command_open_uris (session, cmd->args, cmd->arg, cmd->user_time);
+ break;
+ case EPHY_SESSION_CMD_MAYBE_OPEN_WINDOW:
+ /* FIXME: maybe just check for normal windows? */
+ if (priv->windows == NULL &&
+ priv->tool_windows == NULL)
+ {
+ ephy_shell_new_tab_full (ephy_shell_get_default (),
+ NULL /* window */, NULL /* tab */,
+ NULL /* URL */,
+ EPHY_NEW_TAB_IN_NEW_WINDOW |
+ EPHY_NEW_TAB_HOME_PAGE,
+ EPHY_EMBED_CHROME_ALL,
+ FALSE /* is popup? */,
+ cmd->user_time);
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ /* Look if there's anything else to dispatch */
+ if (g_queue_is_empty (priv->queue) ||
+ priv->resume_dialog != NULL)
+ {
+ priv->queue_idle_id = 0;
+ run_again = FALSE;
+ }
+
+ /* This unrefs the shell! */
+ session_command_free (cmd);
+
+ return run_again;
+}
+
+static void
+session_command_queue_next (EphySession *session)
+{
+ EphySessionPrivate *priv = session->priv;
+
+ LOG ("queue_next");
+
+ if (!g_queue_is_empty (priv->queue) &&
+ priv->resume_dialog == NULL &&
+ priv->queue_idle_id == 0)
+ {
+ priv->queue_idle_id =
+ g_idle_add ((GSourceFunc) session_command_dispatch,
+ session);
+ }
+}
+
+static void
+session_command_queue_clear (EphySession *session)
+{
+ EphySessionPrivate *priv = session->priv;
+
+ if (priv->resume_dialog != NULL)
+ {
+ gtk_widget_destroy (priv->resume_dialog);
+ /* destroying the resume dialogue will set this to NULL */
+ g_assert (priv->resume_dialog == NULL);
+ }
+
+ if (priv->queue_idle_id != 0)
+ {
+ g_source_remove (priv->queue_idle_id);
+ priv->queue_idle_id = 0;
+ }
+
+ if (priv->queue != NULL)
+ {
+ g_queue_foreach (priv->queue, (GFunc) session_command_free, NULL);
+ g_queue_free (priv->queue);
+ priv->queue = NULL;
+ }
+}
+
+/* EphyExtensionIface implementation */
+
static void
impl_attach_window (EphyExtension *extension,
EphyWindow *window)
@@ -263,19 +661,33 @@ impl_detach_window (EphyExtension *extension,
*/
}
+/* Class implementation */
+
static void
ephy_session_init (EphySession *session)
{
- session->priv = EPHY_SESSION_GET_PRIVATE (session);
+ EphySessionPrivate *priv;
+ GnomeClient *client;
LOG ("EphySession initialising");
+
+ priv = session->priv = EPHY_SESSION_GET_PRIVATE (session);
+
+ priv->queue = g_queue_new ();
+
+ client = gnome_master_client ();
+ g_signal_connect (client, "save-yourself",
+ G_CALLBACK (save_yourself_cb), session);
+ g_signal_connect (client, "die",
+ G_CALLBACK (die_cb), session);
}
static void
ephy_session_dispose (GObject *object)
{
- EphySession *session = EPHY_SESSION(object);
+ EphySession *session = EPHY_SESSION (object);
EphySessionPrivate *priv = session->priv;
+ GnomeClient *client;
LOG ("EphySession disposing");
@@ -287,6 +699,14 @@ ephy_session_dispose (GObject *object)
session_delete (session, SESSION_CRASHED);
}
+ session_command_queue_clear (session);
+
+ client = gnome_master_client ();
+ g_signal_handlers_disconnect_by_func
+ (client, G_CALLBACK (save_yourself_cb), session);
+ g_signal_handlers_disconnect_by_func
+ (client, G_CALLBACK (die_cb), session);
+
parent_class->dispose (object);
}
@@ -301,7 +721,7 @@ ephy_session_finalize (GObject *object)
g_list_free (session->priv->windows);
g_list_free (session->priv->tool_windows);
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ parent_class->finalize (object);
}
static void
@@ -363,100 +783,7 @@ ephy_session_class_init (EphySessionClass *class)
g_type_class_add_private (object_class, sizeof (EphySessionPrivate));
}
-static gboolean
-offer_to_resume (EphySession *session,
- guint32 user_time)
-{
- GtkWidget *dialog;
- int response;
-
- dialog = gtk_message_dialog_new
- (NULL,
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_NONE,
- _("Recover previous browser windows and tabs?"));
-
- gtk_message_dialog_format_secondary_text
- (GTK_MESSAGE_DIALOG (dialog),
- _("Epiphany appears to have exited unexpectedly the last time "
- "it was run. You can recover the opened windows and tabs."));
-
- gtk_dialog_add_button (GTK_DIALOG (dialog),
- _("_Don't Recover"), GTK_RESPONSE_CANCEL);
- gtk_dialog_add_button (GTK_DIALOG (dialog),
- _("_Recover"), GTK_RESPONSE_ACCEPT);
-
- gtk_window_set_title (GTK_WINDOW (dialog), _("Crash Recovery"));
- gtk_window_set_icon_name (GTK_WINDOW (dialog), "web-browser");
- gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
-
- session->priv->resume_dialog = dialog;
-
- ephy_gui_window_update_user_time (session->priv->resume_dialog,
- user_time);
-
- gtk_window_set_auto_startup_notification (FALSE);
- response = gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_window_set_auto_startup_notification (TRUE);
-
- gtk_widget_destroy (dialog);
-
- session->priv->resume_dialog = NULL;
-
- return (response == GTK_RESPONSE_ACCEPT);
-}
-
-/**
- * ephy_session_autoresume:
- * @session: a #EphySession
- * @user_time: a timestamp, or 0
- *
- * Resume a crashed session when necessary (interactive)
- *
- * Return value: TRUE if handled; windows have actually
- * been opened or the dialog from a previous instance
- * has been re-presented to the user.
- **/
-gboolean
-ephy_session_autoresume (EphySession *session,
- guint32 user_time)
-{
- EphySessionPrivate *priv = session->priv;
- char *saved_session;
- gboolean retval = FALSE;
-
- LOG ("ephy_session_autoresume");
-
- if (priv->windows != NULL || priv->tool_windows != NULL) return FALSE;
-
- if (priv->resume_dialog)
- {
- ephy_gui_window_update_user_time (priv->resume_dialog,
- user_time);
- ephy_gui_window_present (GTK_WINDOW (priv->resume_dialog),
- user_time);
- return TRUE;
- }
-
- saved_session = get_session_filename (SESSION_CRASHED);
-
- if (g_file_test (saved_session, G_FILE_TEST_EXISTS)
- && offer_to_resume (session, user_time))
- {
- priv->dont_save = TRUE;
- retval = ephy_session_load (session, saved_session,
- 0 /* since we've shown the dialogue */);
- priv->dont_save = FALSE;
- ephy_session_save (session, SESSION_CRASHED);
- }
-
- g_free (saved_session);
-
- /* ensure we don't open a blank window when quitting while resuming */
- return retval || priv->quit_while_resuming;
-}
+/* Implementation */
static void
close_dialog (GtkWidget *widget)
@@ -480,12 +807,15 @@ ephy_session_close (EphySession *session)
/* we have to ref the shell or else we may get finalised between
* destroying the windows and destroying the tool windows
*/
- g_object_ref (ephy_shell);
+ g_object_ref (ephy_shell_get_default ());
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;
+ /* Clear command queue */
+ session_command_queue_clear (session);
+
ephy_embed_shell_prepare_close (embed_shell);
/* there may still be windows open, like dialogues posed from
@@ -513,7 +843,11 @@ ephy_session_close (EphySession *session)
g_list_free (windows);
session->priv->dont_save = FALSE;
- g_object_unref (ephy_shell);
+
+ /* Clear command queue */
+ session_command_queue_clear (session);
+
+ g_object_unref (ephy_shell_get_default ());
}
static int
@@ -861,7 +1195,7 @@ restore_geometry (GtkWindow *window,
* ephy_session_load:
* @session: a #EphySession
* @filename: the path of the source file
- * @user_time: a timestamp, or 0
+ * @user_time: a user_time, or 0
*
* Load a session from disk, restoring the windows and their state
*
@@ -872,6 +1206,7 @@ ephy_session_load (EphySession *session,
const char *filename,
guint32 user_time)
{
+ EphySessionPrivate *priv = session->priv;
xmlDocPtr doc;
xmlNodePtr child;
EphyWindow *window;
@@ -890,6 +1225,10 @@ ephy_session_load (EphySession *session,
return FALSE;
}
+ g_object_ref (ephy_shell_get_default ());
+
+ priv->dont_save = TRUE;
+
child = xmlDocGetRootElement (doc);
/* skip the session node */
@@ -946,7 +1285,13 @@ ephy_session_load (EphySession *session,
xmlFreeDoc (doc);
- return (session->priv->windows != NULL || session->priv->tool_windows != NULL);
+ priv->dont_save = FALSE;
+
+ ephy_session_save (session, SESSION_CRASHED);
+
+ g_object_unref (ephy_shell_get_default ());
+
+ return (priv->windows != NULL || priv->tool_windows != NULL);
}
/**
@@ -1034,3 +1379,72 @@ ephy_session_get_active_window (EphySession *session)
return window;
}
+
+/**
+ * ephy_session_queue_command:
+ * @session: a #EphySession
+ **/
+void
+ephy_session_queue_command (EphySession *session,
+ EphySessionCommand command,
+ const char *arg,
+ char **args,
+ guint32 user_time,
+ gboolean priority)
+{
+ EphySessionPrivate *priv;
+ GList *element;
+ SessionCommand *cmd;
+
+ LOG ("queue_command command:%d", command);
+
+ g_return_if_fail (EPHY_IS_SESSION (session));
+ g_return_if_fail (command != EPHY_SESSION_CMD_OPEN_URIS || args != NULL);
+
+ priv = session->priv;
+
+ /* First look if the same command is already queued */
+ if (command > EPHY_SESSION_CMD_RESUME_SESSION &&
+ command < EPHY_SESSION_CMD_OPEN_URIS)
+ {
+ element = g_queue_find_custom (priv->queue,
+ GINT_TO_POINTER (command),
+ (GCompareFunc) session_command_find);
+ if (element != NULL)
+ {
+ cmd = (SessionCommand *) element->data;
+
+ if ((command == EPHY_SESSION_CMD_LOAD_SESSION &&
+ strcmp (cmd->arg, arg) == 0) ||
+ command == EPHY_SESSION_CMD_OPEN_BOOKMARKS_EDITOR ||
+ command == EPHY_SESSION_CMD_RESUME_SESSION)
+ {
+ cmd->user_time = user_time;
+ g_queue_remove (priv->queue, cmd);
+ g_queue_push_tail (priv->queue, cmd);
+
+ return;
+ }
+ }
+ }
+
+ /* FIXME: use g_slice_new */
+ cmd = g_new0 (SessionCommand, 1);
+ cmd->command = command;
+ cmd->arg = arg ? g_strdup (arg) : NULL;
+ cmd->args = args ? g_strdupv (args) : NULL;
+ cmd->user_time = user_time;
+ /* This ref is released in session_command_free */
+ g_object_ref (ephy_shell_get_default ());
+
+ if (priority)
+ {
+ g_queue_push_head (priv->queue, cmd);
+ }
+ else
+ {
+ g_queue_push_tail (priv->queue, cmd);
+ }
+
+ session_command_queue_next (session);
+}
diff --git a/src/ephy-session.h b/src/ephy-session.h
index 025f8425d..2bdc26fd6 100644
--- a/src/ephy-session.h
+++ b/src/ephy-session.h
@@ -39,8 +39,19 @@ G_BEGIN_DECLS
#define EPHY_SESSION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_SESSION, EphySessionClass))
typedef struct _EphySession EphySession;
-typedef struct _EphySessionClass EphySessionClass;
typedef struct _EphySessionPrivate EphySessionPrivate;
+typedef struct _EphySessionClass EphySessionClass;
+
+typedef enum
+{
+ EPHY_SESSION_CMD_RESUME_SESSION,
+ EPHY_SESSION_CMD_LOAD_SESSION,
+ EPHY_SESSION_CMD_OPEN_BOOKMARKS_EDITOR,
+ EPHY_SESSION_CMD_OPEN_URIS,
+ EPHY_SESSION_CMD_MAYBE_OPEN_WINDOW,
+ EPHY_SESSION_CMD_LAST
+
+} EphySessionCommand;
struct _EphySession
{
@@ -66,9 +77,6 @@ gboolean ephy_session_load (EphySession *session,
const char *filename,
guint32 user_time);
-gboolean ephy_session_autoresume (EphySession *session,
- guint32 user_time);
-
void ephy_session_close (EphySession *session);
GList *ephy_session_get_windows (EphySession *session);
@@ -76,9 +84,16 @@ GList *ephy_session_get_windows (EphySession *session);
void ephy_session_add_window (EphySession *session,
GtkWindow *window);
-void ephy_session_remove_window (EphySession *session,
+void ephy_session_remove_window (EphySession *session,
GtkWindow *window);
+void ephy_session_queue_command (EphySession *session,
+ EphySessionCommand op,
+ const char *arg,
+ char **args,
+ guint32 user_time,
+ gboolean priority);
+
G_END_DECLS
#endif
diff --git a/src/epiphany.defs b/src/epiphany.defs
index f70c2addb..9d0b81adb 100644
--- a/src/epiphany.defs
+++ b/src/epiphany.defs
@@ -2968,15 +2968,6 @@
)
)
-(define-method autoresume
- (of-object "EphySession")
- (c-name "ephy_session_autoresume")
- (return-type "gboolean")
- (parameters
- '("guint32" "user_time")
- )
-)
-
(define-method close
(of-object "EphySession")
(c-name "ephy_session_close")