aboutsummaryrefslogtreecommitdiffstats
path: root/embed
diff options
context:
space:
mode:
authorGustavo Noronha Silva <gns@gnome.org>2013-02-10 02:43:02 +0800
committerGustavo Noronha Silva <gns@gnome.org>2013-02-12 23:55:51 +0800
commitce7ab1e34804d9f7529bed13267f4619c37e32d9 (patch)
tree69f2a2e2dbce017980352b1afd57e1b38c8f278b /embed
parent551eb0cec6469ece8e826411d65bf806ec043142 (diff)
downloadgsoc2013-epiphany-ce7ab1e34804d9f7529bed13267f4619c37e32d9.tar
gsoc2013-epiphany-ce7ab1e34804d9f7529bed13267f4619c37e32d9.tar.gz
gsoc2013-epiphany-ce7ab1e34804d9f7529bed13267f4619c37e32d9.tar.bz2
gsoc2013-epiphany-ce7ab1e34804d9f7529bed13267f4619c37e32d9.tar.lz
gsoc2013-epiphany-ce7ab1e34804d9f7529bed13267f4619c37e32d9.tar.xz
gsoc2013-epiphany-ce7ab1e34804d9f7529bed13267f4619c37e32d9.tar.zst
gsoc2013-epiphany-ce7ab1e34804d9f7529bed13267f4619c37e32d9.zip
Only load pages when their tab is switched to upon session restore
Firefox has led the way implementing this behaviour to improve the experience of restoring a session with lots of tabs. By delaying the loading of pages to when the user shows interest in them, the time it takes for the browser to become usable is diminished, and less pages are loaded in parallel, which improves load time for the first pages the user sees. It also has the advante of displaying less HTTP Basic Auth dialogs, when the user has many tabs pointed to the same server. https://bugzilla.gnome.org/show_bug.cgi?id=675302
Diffstat (limited to 'embed')
-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
6 files changed, 168 insertions, 5 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,