aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXan Lopez <xan@gnome.org>2010-05-03 19:39:00 +0800
committerXan Lopez <xan@gnome.org>2010-05-03 19:40:33 +0800
commitd5474fc558fccf705a005475d03681a6311b7cef (patch)
tree0a1443a19540d879222aa6c38ebdae5b2a14e236
parentea394862505225b631b677d33aa6c9203f850486 (diff)
downloadgsoc2013-epiphany-d5474fc558fccf705a005475d03681a6311b7cef.tar.gz
gsoc2013-epiphany-d5474fc558fccf705a005475d03681a6311b7cef.tar.zst
gsoc2013-epiphany-d5474fc558fccf705a005475d03681a6311b7cef.zip
ephy-session: use an infobar to inform the user about session restoration
Much nicer than a modal dialog that blocks the browser initialization.
-rw-r--r--src/ephy-session.c288
-rw-r--r--src/ephy-session.h1
2 files changed, 196 insertions, 93 deletions
diff --git a/src/ephy-session.c b/src/ephy-session.c
index e591e1c9f..d7cf59928 100644
--- a/src/ephy-session.c
+++ b/src/ephy-session.c
@@ -65,7 +65,8 @@ struct _EphySessionPrivate
{
GList *windows;
GList *tool_windows;
- GtkWidget *resume_dialog;
+ GtkWidget *resume_infobar;
+ GtkWidget *resume_window;
GQueue *queue;
guint queue_idle_id;
@@ -74,6 +75,7 @@ struct _EphySessionPrivate
guint dont_save : 1;
guint quit_while_resuming : 1;
+ guint loading_homepage : 1;
};
#define BOOKMARKS_EDITOR_ID "BookmarksEditor"
@@ -469,48 +471,43 @@ session_command_find (const SessionCommand *cmd,
}
static void
-resume_dialog_response_cb (GtkWidget *dialog,
- int response,
- EphySession *session)
+resume_infobar_response_cb (GtkWidget *info_bar,
+ int response,
+ EphySession *session)
{
guint32 user_time;
+ EphySessionPrivate *priv = session->priv;
- LOG ("resume_dialog_response_cb response:%d", response);
+ LOG ("resume_infobar_response_cb response:%d", response);
- gtk_widget_hide (dialog);
+ gtk_widget_hide (info_bar);
user_time = gtk_get_current_event_time ();
- if (response == GTK_RESPONSE_ACCEPT)
+ priv->dont_save = FALSE;
+
+ gtk_widget_destroy (info_bar);
+ priv->resume_infobar = NULL;
+
+ if (response == GTK_RESPONSE_YES)
{
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)
+resume_infobar_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);
+ LOG ("resume_window_infobar_weak_ref_cb");
+ priv->dont_save = FALSE;
session_command_queue_next (session);
-
- g_object_unref (ephy_shell_get_default ());
}
static void
@@ -518,7 +515,6 @@ session_command_autoresume (EphySession *session,
guint32 user_time)
{
EphySessionPrivate *priv = session->priv;
- GtkWidget *dialog;
GFile *saved_session_file;
char *saved_session_file_path;
gboolean crashed_session;
@@ -536,10 +532,10 @@ session_command_autoresume (EphySession *session,
priv->tool_windows != NULL)
{
/* FIXME can this happen? */
- if (priv->resume_dialog != NULL)
+ if (priv->resume_infobar != NULL)
{
- gtk_widget_hide (priv->resume_dialog);
- gtk_widget_destroy (priv->resume_dialog);
+ gtk_widget_hide (priv->resume_infobar);
+ gtk_widget_destroy (priv->resume_infobar);
}
ephy_session_queue_command (session,
@@ -549,55 +545,17 @@ session_command_autoresume (EphySession *session,
return;
}
- if (priv->resume_dialog)
+ if (priv->resume_window)
{
- gtk_window_present_with_time (GTK_WINDOW (priv->resume_dialog),
+ gtk_window_present_with_time (GTK_WINDOW (priv->resume_window),
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), EPHY_STOCK_EPHY);
- gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER);
- gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), FALSE);
- 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);
+ ephy_session_queue_command (session,
+ EPHY_SESSION_CMD_MAYBE_OPEN_WINDOW_RESTORE,
+ NULL, NULL, user_time, FALSE);
}
static void
@@ -620,9 +578,12 @@ session_command_open_uris (EphySession *session,
EphyShell *shell;
EphyWindow *window;
EphyEmbed *embed;
+ EphySessionPrivate *priv;
EphyNewTabFlags flags = 0;
guint i;
+ priv = session->priv;
+
shell = ephy_shell_get_default ();
g_object_ref (shell);
@@ -660,13 +621,28 @@ session_command_open_uris (EphySession *session,
request = webkit_network_request_new (url);
}
- embed = ephy_shell_new_tab_full (shell, window,
- NULL /* parent tab */,
- request,
- flags | page_flags,
- EPHY_WEB_VIEW_CHROME_ALL,
- FALSE /* is popup? */,
- user_time);
+ /* For the first URI, if we have a valid recovery
+ * window, reuse the already existing embed instead of
+ * creating a new one */
+ if (i == 0 && priv->resume_window != NULL)
+ {
+ EphyWebView *web_view;
+
+ embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (priv->resume_window));
+ web_view = ephy_embed_get_web_view (embed);
+ ephy_web_view_load_url (web_view, url);
+ }
+ else
+ {
+ embed = ephy_shell_new_tab_full (shell, window,
+ NULL /* parent tab */,
+ request,
+ flags | page_flags,
+ EPHY_WEB_VIEW_CHROME_ALL,
+ FALSE /* is popup? */,
+ user_time);
+ }
+
if (request)
g_object_unref (request);
@@ -676,6 +652,46 @@ session_command_open_uris (EphySession *session,
g_object_unref (shell);
}
+static void
+send_no_response_cb (GtkButton *button, GtkInfoBar *info_bar)
+{
+ gtk_info_bar_response (info_bar, GTK_RESPONSE_NO);
+}
+
+static void
+send_yes_response_cb (GtkButton *button, GtkInfoBar *info_bar)
+{
+ gtk_info_bar_response (info_bar, GTK_RESPONSE_YES);
+}
+
+static void
+loading_homepage_cb (EphyWebView *view, EphySession *session)
+{
+ EphySessionPrivate *priv = session->priv;
+
+ priv->loading_homepage = TRUE;
+}
+
+static void
+new_document_now_cb (EphyWebView *view, const char *uri, EphySession *session)
+{
+ EphySessionPrivate *priv = session->priv;
+
+ if (priv->loading_homepage)
+ {
+ priv->loading_homepage = FALSE;
+ return;
+ }
+
+ if (priv->resume_infobar)
+ {
+ EphyEmbed *embed = EPHY_GET_EMBED_FROM_EPHY_WEB_VIEW (view);
+ ephy_embed_remove_top_widget (embed, priv->resume_infobar);
+ priv->resume_infobar = NULL;
+ priv->resume_window = NULL;
+ }
+}
+
static gboolean
session_command_dispatch (EphySession *session)
{
@@ -717,6 +733,73 @@ session_command_dispatch (EphySession *session)
cmd->user_time);
}
break;
+ case EPHY_SESSION_CMD_MAYBE_OPEN_WINDOW_RESTORE:
+ /* FIXME: maybe just check for normal windows? */
+ if (priv->windows == NULL &&
+ priv->tool_windows == NULL)
+ {
+ GtkWidget *info_bar;
+ GtkWidget *action_area;
+ GtkWidget *button_box;
+ GtkWidget *action_button;
+ GtkWidget *content_area;
+ GtkWidget *label;
+ EphyEmbed *embed;
+ EphyWebView *view;
+
+ session->priv->dont_save = TRUE;
+
+ embed = ephy_shell_new_tab_full (ephy_shell_get_default (),
+ NULL /* window */, NULL /* tab */,
+ NULL /* Networ kRequest */,
+ EPHY_NEW_TAB_IN_NEW_WINDOW |
+ EPHY_NEW_TAB_HOME_PAGE,
+ EPHY_WEB_VIEW_CHROME_ALL,
+ FALSE /* is popup? */,
+ cmd->user_time);
+
+ info_bar = gtk_info_bar_new ();
+
+ session->priv->resume_infobar = info_bar;
+ session->priv->resume_window = gtk_widget_get_toplevel (GTK_WIDGET (embed));
+
+ action_area = gtk_info_bar_get_action_area (GTK_INFO_BAR (info_bar));
+ button_box = gtk_hbutton_box_new ();
+ gtk_container_add (GTK_CONTAINER (action_area), button_box);
+
+ action_button = gtk_button_new_with_label (_("Don't recover"));
+ g_signal_connect (action_button, "clicked",
+ G_CALLBACK (send_no_response_cb), info_bar);
+ gtk_box_pack_start (GTK_BOX (button_box), action_button, FALSE, FALSE, 0);
+
+ action_button = gtk_button_new_with_label (_("Recover session"));
+ g_signal_connect (action_button, "clicked",
+ G_CALLBACK (send_yes_response_cb), info_bar);
+ gtk_box_pack_start (GTK_BOX (button_box), action_button, FALSE, FALSE, 0);
+
+ label = gtk_label_new (_("Do you want to recover the previous browser windows and tabs?"));
+ content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (info_bar));
+ gtk_container_add (GTK_CONTAINER (content_area), label);
+ gtk_widget_show_all (info_bar);
+
+ g_signal_connect (info_bar, "response",
+ G_CALLBACK (resume_infobar_response_cb), session);
+
+ g_object_weak_ref (G_OBJECT (info_bar),
+ (GWeakNotify) resume_infobar_weak_ref_cb,
+ session);
+
+ ephy_embed_add_top_widget (embed, info_bar, FALSE);
+
+ view = ephy_embed_get_web_view (embed);
+
+ g_signal_connect (view, "loading-homepage",
+ G_CALLBACK (loading_homepage_cb), session);
+
+ g_signal_connect (view, "new-document-now",
+ G_CALLBACK (new_document_now_cb), session);
+ }
+ break;
default:
g_assert_not_reached ();
break;
@@ -724,7 +807,7 @@ session_command_dispatch (EphySession *session)
/* Look if there's anything else to dispatch */
if (g_queue_is_empty (priv->queue) ||
- priv->resume_dialog != NULL)
+ priv->resume_window != NULL)
{
priv->queue_idle_id = 0;
run_again = FALSE;
@@ -744,7 +827,7 @@ session_command_queue_next (EphySession *session)
LOG ("queue_next");
if (!g_queue_is_empty (priv->queue) &&
- priv->resume_dialog == NULL &&
+ priv->resume_infobar == NULL &&
priv->queue_idle_id == 0)
{
priv->queue_idle_id =
@@ -758,13 +841,6 @@ 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);
@@ -987,7 +1063,7 @@ ephy_session_close (EphySession *session)
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;
+ priv->quit_while_resuming = priv->resume_window != NULL;
/* Clear command queue */
session_command_queue_clear (session);
@@ -1359,6 +1435,9 @@ parse_embed (xmlNodePtr child,
EphyWindow *window,
EphySession *session)
{
+ gboolean loaded_first = FALSE;
+ EphySessionPrivate *priv = session->priv;
+
while (child != NULL)
{
if (strcmp ((char *) child->name, "embed") == 0)
@@ -1389,11 +1468,26 @@ parse_embed (xmlNodePtr child,
strcmp ((const char *) url, "about:blank") == 0)
{
recover_url = (char *) url;
+
+ /* Reuse the window holding the recovery infobar instead of creating a new one */
+ if (loaded_first == FALSE && priv->resume_window != NULL)
+ {
+ EphyWebView *web_view;
+ EphyEmbed *embed;
+
+ embed = ephy_embed_container_get_active_child (EPHY_EMBED_CONTAINER (priv->resume_window));
+ web_view = ephy_embed_get_web_view (embed);
+ ephy_web_view_load_url(web_view, recover_url);
+ }
+ else
+ {
+ ephy_shell_new_tab (ephy_shell, window, NULL, recover_url,
+ EPHY_NEW_TAB_IN_EXISTING_WINDOW |
+ EPHY_NEW_TAB_OPEN_PAGE |
+ EPHY_NEW_TAB_APPEND_LAST);
+ }
- ephy_shell_new_tab (ephy_shell, window, NULL, recover_url,
- EPHY_NEW_TAB_IN_EXISTING_WINDOW |
- EPHY_NEW_TAB_OPEN_PAGE |
- EPHY_NEW_TAB_APPEND_LAST);
+ loaded_first = TRUE;
}
else if (was_loading && url != NULL &&
strcmp ((const char *) url, "about:blank") != 0)
@@ -1496,6 +1590,7 @@ ephy_session_load (EphySession *session,
GtkWidget *widget = NULL;
GFile *save_to_file;
char *save_to_path;
+ gboolean first_window_created = FALSE;
LOG ("ephy_sesion_load %s", filename);
@@ -1525,7 +1620,14 @@ ephy_session_load (EphySession *session,
{
xmlChar *tmp;
- window = ephy_window_new ();
+ if (first_window_created == FALSE && priv->resume_window != NULL)
+ {
+ window = EPHY_WINDOW (priv->resume_window);
+ first_window_created = TRUE;
+ }
+ else
+ window = ephy_window_new ();
+
widget = GTK_WIDGET (window);
restore_geometry (GTK_WINDOW (widget), child);
@@ -1754,9 +1856,9 @@ ephy_session_queue_command (EphySession *session,
session_command_queue_next (session);
- if (priv->resume_dialog != NULL)
+ if (priv->resume_window != NULL)
{
- gtk_window_present_with_time (GTK_WINDOW (priv->resume_dialog),
+ gtk_window_present_with_time (GTK_WINDOW (priv->resume_window),
user_time);
}
}
diff --git a/src/ephy-session.h b/src/ephy-session.h
index 536fb6986..4dbb496c5 100644
--- a/src/ephy-session.h
+++ b/src/ephy-session.h
@@ -50,6 +50,7 @@ typedef enum
EPHY_SESSION_CMD_OPEN_BOOKMARKS_EDITOR,
EPHY_SESSION_CMD_OPEN_URIS,
EPHY_SESSION_CMD_MAYBE_OPEN_WINDOW,
+ EPHY_SESSION_CMD_MAYBE_OPEN_WINDOW_RESTORE,
EPHY_SESSION_CMD_LAST
} EphySessionCommand;