aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--embed/ephy-embed-shell.c24
-rw-r--r--embed/ephy-embed-shell.h3
-rw-r--r--embed/ephy-embed.c101
-rw-r--r--embed/ephy-embed.h3
-rw-r--r--embed/ephy-web-view.c38
-rw-r--r--embed/ephy-web-view.h4
-rw-r--r--src/ephy-notebook.c4
-rw-r--r--src/ephy-session.c23
-rw-r--r--src/ephy-shell.c9
-rw-r--r--src/ephy-shell.h3
10 files changed, 197 insertions, 15 deletions
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index ea45a1433..b4366b2f4 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -62,6 +62,7 @@ enum
DOWNLOAD_ADDED,
DOWNLOAD_REMOVED,
PREPARE_CLOSE,
+ RESTORED_WINDOW,
LAST_SIGNAL
};
@@ -263,6 +264,12 @@ ephy_embed_shell_prepare_close (EphyEmbedShell *shell)
g_signal_emit (shell, signals[PREPARE_CLOSE], 0);
}
+void
+ephy_embed_shell_restored_window (EphyEmbedShell *shell)
+{
+ g_signal_emit (shell, signals[RESTORED_WINDOW], 0);
+}
+
static void
ephy_embed_shell_set_property (GObject *object,
guint prop_id,
@@ -385,6 +392,23 @@ ephy_embed_shell_class_init (EphyEmbedShellClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+/**
+ * EphyEmbedShell::finished-restoring-window:
+ * @shell: the #EphyEmbedShell
+ *
+ * The ::finished-restoring-window signal is emitted when the
+ * session finishes restoring a window.
+ **/
+ signals[RESTORED_WINDOW] =
+ g_signal_new ("window-restored",
+ EPHY_TYPE_EMBED_SHELL,
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EphyEmbedShellClass, restored_window),
+ 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 e9973a288..45261e93b 100644
--- a/embed/ephy-embed-shell.h
+++ b/embed/ephy-embed-shell.h
@@ -72,6 +72,8 @@ struct _EphyEmbedShellClass
void (* prepare_close) (EphyEmbedShell *shell);
+ void (* restored_window) (EphyEmbedShell *shell);
+
/*< private >*/
GObject * (* get_embed_single) (EphyEmbedShell *shell);
};
@@ -83,6 +85,7 @@ GObject *ephy_embed_shell_get_encodings (EphyEmbedShell
GObject *ephy_embed_shell_get_embed_single (EphyEmbedShell *shell);
GObject *ephy_embed_shell_get_adblock_manager (EphyEmbedShell *shell);
void ephy_embed_shell_prepare_close (EphyEmbedShell *shell);
+void ephy_embed_shell_restored_window (EphyEmbedShell *shell);
void ephy_embed_shell_set_page_setup (EphyEmbedShell *shell,
GtkPageSetup *page_setup);
GtkPageSetup *ephy_embed_shell_get_page_setup (EphyEmbedShell *shell);
diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c
index 5d9f631bd..8ead506a5 100644
--- a/embed/ephy-embed.c
+++ b/embed/ephy-embed.c
@@ -43,13 +43,15 @@
#include <webkit/webkit.h>
#endif
-static void ephy_embed_constructed (GObject *object);
+static void ephy_embed_constructed (GObject *object);
#ifndef HAVE_WEBKIT2
-static gboolean ephy_embed_inspect_show_cb (WebKitWebInspector *inspector,
- EphyEmbed *embed);
-static gboolean ephy_embed_inspect_close_cb (WebKitWebInspector *inspector,
- EphyEmbed *embed);
+static gboolean ephy_embed_inspect_show_cb (WebKitWebInspector *inspector,
+ EphyEmbed *embed);
+static gboolean ephy_embed_inspect_close_cb (WebKitWebInspector *inspector,
+ EphyEmbed *embed);
#endif
+static void ephy_embed_restored_window_cb (EphyEmbedShell *shell,
+ EphyEmbed *embed);
#define EPHY_EMBED_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_EMBED, EphyEmbedPrivate))
@@ -79,6 +81,8 @@ struct _EphyEmbedPrivate
GtkWidget *fullscreen_message_label;
char *fullscreen_string;
+ WebKitNetworkRequest *delayed_request;
+
GtkWidget *overview;
guint overview_mode : 1;
GSList *messages;
@@ -415,6 +419,8 @@ ephy_embed_dispose (GObject *object)
priv->adblock_handler_id = 0;
}
+ g_clear_object (&priv->delayed_request);
+
G_OBJECT_CLASS (ephy_embed_parent_class)->dispose (object);
}
@@ -423,8 +429,11 @@ ephy_embed_finalize (GObject *object)
{
EphyEmbed *embed = EPHY_EMBED (object);
EphyEmbedPrivate *priv = embed->priv;
+ EphyEmbedShell *shell = ephy_embed_shell_get_default ();
GSList *list;
+ g_signal_handlers_disconnect_by_func(shell, ephy_embed_restored_window_cb, embed);
+
list = priv->destroy_on_transition_list;
for (; list; list = list->next) {
GtkWidget *widget = GTK_WIDGET (list->data);
@@ -862,10 +871,50 @@ setup_adblock (GSettings *settings,
#endif
static void
+ephy_embed_maybe_load_delayed_request (EphyEmbed *embed)
+{
+ EphyEmbedPrivate *priv = embed->priv;
+ EphyWebView *web_view;
+
+ if (!priv->delayed_request)
+ return;
+
+ web_view = ephy_embed_get_web_view (embed);
+
+ ephy_web_view_load_request (web_view, priv->delayed_request);
+ g_clear_object (&priv->delayed_request);
+
+ /* This is to allow UI elements watching load status to show that the page is
+ * loading as soon as possible.
+ */
+#ifdef HAVE_WEBKIT2
+ g_signal_emit_by_name (web_view, "load-changed", WEBKIT_LOAD_STARTED);
+#else
+ g_object_notify (G_OBJECT (web_view), "load-status");
+#endif
+}
+
+static void
+ephy_embed_restored_window_cb (EphyEmbedShell *shell, EphyEmbed *embed)
+{
+ if (!gtk_widget_get_mapped (GTK_WIDGET (embed)))
+ return;
+
+ ephy_embed_maybe_load_delayed_request (embed);
+}
+
+static void
+ephy_embed_mapped_cb (GtkWidget *widget, gpointer data)
+{
+ ephy_embed_maybe_load_delayed_request ((EphyEmbed*)widget);
+}
+
+static void
ephy_embed_constructed (GObject *object)
{
EphyEmbed *embed = (EphyEmbed*)object;
EphyEmbedPrivate *priv = embed->priv;
+ EphyEmbedShell *shell = ephy_embed_shell_get_default ();
#ifndef HAVE_WEBKIT2
GtkWidget *scrolled_window;
#endif
@@ -879,6 +928,12 @@ ephy_embed_constructed (GObject *object)
WebKitWebInspector *inspector;
GtkWidget *overlay;
+ g_signal_connect (shell, "window-restored",
+ G_CALLBACK (ephy_embed_restored_window_cb), embed);
+
+ g_signal_connect (embed, "map",
+ G_CALLBACK (ephy_embed_mapped_cb), NULL);
+
/* Skeleton */
web_view = WEBKIT_WEB_VIEW (ephy_web_view_new ());
#ifndef HAVE_WEBKIT2
@@ -1161,6 +1216,42 @@ ephy_embed_get_overview_mode (EphyEmbed *embed)
}
/**
+ * ephy_embed_set_delayed_load_request:
+ * @embed: a #EphyEmbed
+ * @request: a #WebKitNetworkRequest
+ *
+ * Sets the #WebKitNetworkRequest that should be loaded when the tab this embed
+ * is on is switched to.
+ */
+void
+ephy_embed_set_delayed_load_request (EphyEmbed *embed, WebKitNetworkRequest *request)
+{
+ g_return_if_fail (EPHY_IS_EMBED (embed));
+ g_return_if_fail (WEBKIT_IS_NETWORK_REQUEST (request));
+
+ g_clear_object (&embed->priv->delayed_request);
+
+ g_object_ref (request);
+ embed->priv->delayed_request = request;
+}
+
+/**
+ * ephy_embed_has_load_pending:
+ * @embed: a #EphyEmbed
+ *
+ * Checks whether a load has been delayed for this #EphyEmbed.
+ *
+ * Returns: %TRUE or %FALSE
+ */
+gboolean
+ephy_embed_has_load_pending (EphyEmbed *embed)
+{
+ g_return_val_if_fail (EPHY_IS_EMBED (embed), FALSE);
+
+ return !!embed->priv->delayed_request;
+}
+
+/**
* ephy_embed_get_overview:
* @embed: a #EphyEmbed
*
diff --git a/embed/ephy-embed.h b/embed/ephy-embed.h
index 7820318d8..afa007e60 100644
--- a/embed/ephy-embed.h
+++ b/embed/ephy-embed.h
@@ -62,6 +62,9 @@ void ephy_embed_auto_download_url (EphyEmbed *embed,
const char *url);
void ephy_embed_entering_fullscreen (EphyEmbed *embed);
void ephy_embed_leaving_fullscreen (EphyEmbed *embed);
+void ephy_embed_set_delayed_load_request (EphyEmbed *embed,
+ WebKitNetworkRequest *request);
+gboolean ephy_embed_has_load_pending (EphyEmbed *embed);
void ephy_embed_set_overview_mode (EphyEmbed *embed,
gboolean overview_mode);
gboolean ephy_embed_get_overview_mode (EphyEmbed *embed);
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index 84580d056..c3594ee61 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -2370,6 +2370,44 @@ load_status_cb (WebKitWebView *web_view,
#endif
/**
+ * ephy_web_view_set_placeholder:
+ * @view: an #EphyWebView
+ * @uri: uri that will eventually be loaded
+ * @title: last-known title of the page that will eventually be loaded
+ *
+ * Makes the #EphyWebView pretend a page that will eventually be loaded is
+ * already there.
+ *
+ **/
+void
+ephy_web_view_set_placeholder (EphyWebView *view,
+ const char *uri,
+ const char *title)
+{
+ char *html;
+
+ g_return_if_fail (EPHY_IS_WEB_VIEW (view));
+
+ /* We want only the actual load to be the one recorded in history, but
+ * doing a load here is the simplest way to replace the loading
+ * spinner with the favicon. */
+ ephy_web_view_freeze_history (view);
+
+ html = g_markup_printf_escaped ("<head><title>%s</title></head>", title);
+
+#ifdef HAVE_WEBKIT2
+ webkit_web_view_load_alternate_html (WEBKIT_WEB_VIEW (view), html, uri, NULL);
+#else
+ webkit_web_frame_load_alternate_string (webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (view)),
+ html, uri, uri);
+#endif
+
+ g_free (html);
+
+ ephy_web_view_set_address (view, uri);
+}
+
+/**
* ephy_web_view_load_error_page:
* @view: an #EphyWebView
* @uri: uri that caused the failure
diff --git a/embed/ephy-web-view.h b/embed/ephy-web-view.h
index e3f7161ef..52de7814d 100644
--- a/embed/ephy-web-view.h
+++ b/embed/ephy-web-view.h
@@ -165,6 +165,10 @@ const char * ephy_web_view_get_title (EphyWebView
const char * ephy_web_view_get_address (EphyWebView *view);
const char * ephy_web_view_get_title_composite (EphyWebView *view);
+void ephy_web_view_set_placeholder (EphyWebView *view,
+ const char *uri,
+ const char *title);
+
void ephy_web_view_load_error_page (EphyWebView *view,
const char *uri,
EphyWebViewErrorPage page,
diff --git a/src/ephy-notebook.c b/src/ephy-notebook.c
index 2349af8f9..f9a9007c6 100644
--- a/src/ephy-notebook.c
+++ b/src/ephy-notebook.c
@@ -467,12 +467,14 @@ static void
sync_load_status (EphyWebView *view, GParamSpec *pspec, GtkWidget *proxy)
{
GtkWidget *spinner, *icon;
+ EphyEmbed *embed;
spinner = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "spinner"));
icon = GTK_WIDGET (g_object_get_data (G_OBJECT (proxy), "icon"));
g_return_if_fail (spinner != NULL && icon != NULL);
- if (ephy_web_view_is_loading (view))
+ embed = EPHY_GET_EMBED_FROM_EPHY_WEB_VIEW (view);
+ if (ephy_web_view_is_loading (view) && !ephy_embed_has_load_pending (embed))
{
gtk_widget_hide (icon);
gtk_widget_show (spinner);
diff --git a/src/ephy-session.c b/src/ephy-session.c
index 47dfe08bd..82ecf4149 100644
--- a/src/ephy-session.c
+++ b/src/ephy-session.c
@@ -631,7 +631,7 @@ session_tab_new (EphyEmbed *embed)
}
session_tab->title = g_strdup (ephy_web_view_get_title (web_view));
- session_tab->loading = ephy_web_view_is_loading (web_view);
+ session_tab->loading = ephy_web_view_is_loading (web_view) && !ephy_embed_has_load_pending (embed);
return session_tab;
}
@@ -1102,11 +1102,19 @@ session_parse_embed (SessionParserContext *context,
*/
if (!was_loading || is_blank_page)
{
- ephy_shell_new_tab (ephy_shell_get_default (),
- context->window, NULL, url,
- EPHY_NEW_TAB_IN_EXISTING_WINDOW |
- EPHY_NEW_TAB_OPEN_PAGE |
- EPHY_NEW_TAB_APPEND_LAST);
+ EphyNewTabFlags flags;
+ EphyEmbed *embed;
+ EphyWebView *web_view;
+
+ flags = EPHY_NEW_TAB_IN_EXISTING_WINDOW;
+ flags |= EPHY_NEW_TAB_APPEND_LAST;
+ flags |= EPHY_NEW_TAB_DELAYED_OPEN_PAGE;
+
+ embed = ephy_shell_new_tab (ephy_shell_get_default (),
+ context->window, NULL, url, flags);
+
+ web_view = ephy_embed_get_web_view (embed);
+ ephy_web_view_set_placeholder (web_view, url, title);
}
else if (was_loading && url != NULL)
{
@@ -1150,6 +1158,7 @@ session_end_element (GMarkupParseContext *ctx,
if (strcmp (element_name, "window") == 0)
{
GtkWidget *notebook;
+ EphyEmbedShell *shell = ephy_embed_shell_get_default ();
notebook = ephy_window_get_notebook (context->window);
gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), context->active_tab);
@@ -1163,6 +1172,8 @@ session_end_element (GMarkupParseContext *ctx,
gtk_widget_show (GTK_WIDGET (context->window));
}
+ ephy_embed_shell_restored_window (shell);
+
context->window = NULL;
context->active_tab = 0;
context->is_first_window = FALSE;
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index 7fd01d7de..ebdd48fd0 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -730,6 +730,7 @@ ephy_shell_new_tab_full (EphyShell *shell,
gboolean fullscreen_lockdown = FALSE;
gboolean in_new_window = TRUE;
gboolean open_page = FALSE;
+ gboolean delayed_open_page = FALSE;
gboolean jump_to = FALSE;
gboolean active_is_blank = FALSE;
gboolean copy_history = TRUE;
@@ -748,6 +749,7 @@ ephy_shell_new_tab_full (EphyShell *shell,
embed_shell = EPHY_EMBED_SHELL (shell);
if (flags & EPHY_NEW_TAB_OPEN_PAGE) open_page = TRUE;
+ if (flags & EPHY_NEW_TAB_DELAYED_OPEN_PAGE) delayed_open_page = TRUE;
if (flags & EPHY_NEW_TAB_IN_NEW_WINDOW) in_new_window = TRUE;
if (flags & EPHY_NEW_TAB_IN_EXISTING_WINDOW) in_new_window = FALSE;
if (flags & EPHY_NEW_TAB_DONT_COPY_HISTORY) copy_history = FALSE;
@@ -756,7 +758,7 @@ ephy_shell_new_tab_full (EphyShell *shell,
fullscreen_lockdown = g_settings_get_boolean (EPHY_SETTINGS_LOCKDOWN,
EPHY_PREFS_LOCKDOWN_FULLSCREEN);
in_new_window = in_new_window && !fullscreen_lockdown;
- g_return_val_if_fail (open_page == (gboolean)(request != NULL), NULL);
+ g_return_val_if_fail ((open_page || delayed_open_page) == (gboolean)(request != NULL), NULL);
LOG ("Opening new tab parent-window %p parent-embed %p in-new-window:%s jump-to:%s",
parent_window, previous_embed, in_new_window ? "t" : "f", jump_to ? "t" : "f");
@@ -822,7 +824,7 @@ ephy_shell_new_tab_full (EphyShell *shell,
ephy_window_activate_location (window);
ephy_web_view_load_homepage (view);
is_empty = TRUE;
- } else if (flags & EPHY_NEW_TAB_OPEN_PAGE) {
+ } else if (open_page) {
ephy_web_view_load_request (ephy_embed_get_web_view (embed),
request);
@@ -831,7 +833,8 @@ ephy_shell_new_tab_full (EphyShell *shell,
#else
is_empty = ephy_embed_utils_url_is_empty (webkit_network_request_get_uri (request));
#endif
- }
+ } else if (delayed_open_page)
+ ephy_embed_set_delayed_load_request (embed, request);
/* Make sure the initial focus is somewhere sensible and not, for
* example, on the reload button.
diff --git a/src/ephy-shell.h b/src/ephy-shell.h
index f65083a7e..7b250fe26 100644
--- a/src/ephy-shell.h
+++ b/src/ephy-shell.h
@@ -59,6 +59,8 @@ typedef struct _EphyShellPrivate EphyShellPrivate;
* @EPHY_NEW_TAB_HOME_PAGE: loads the home page in the new tab.
* @EPHY_NEW_TAB_NEW_PAGE: legacy synonym for @EPHY_NEW_TAB_HOME_PAGE.
* @EPHY_NEW_TAB_OPEN_PAGE: opens the provided network-request.
+ * @EPHY_NEW_TAB_DELAYED_OPEN_PAGE: store the provided network-request
+ * so that it will be opened when the tab is switched to.
* @EPHY_NEW_TAB_FULLSCREEN_MODE: calls gtk_window_fullscreen on the
* parent window of the new tab.
* @EPHY_NEW_TAB_DONT_SHOW_WINDOW: do not show the window where the new
@@ -85,6 +87,7 @@ typedef enum {
EPHY_NEW_TAB_HOME_PAGE = 1 << 0,
EPHY_NEW_TAB_NEW_PAGE = 1 << 1,
EPHY_NEW_TAB_OPEN_PAGE = 1 << 2,
+ EPHY_NEW_TAB_DELAYED_OPEN_PAGE = 1 << 3,
/* Page mode */
EPHY_NEW_TAB_FULLSCREEN_MODE = 1 << 4,