[epiphany] overview: Remove the overview model from the UI process



commit 0433ac9dafd91664134ae1c300c6841e86a58d91
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Tue Feb 25 18:50:38 2014 +0100

    overview: Remove the overview model from the UI process
    
    Now we query the history and snapshot services directly and the model is
    used only in the web process. This fixes a race condition when the
    overview page is created before the history query has completed leaving
    an empty overview.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=725393

 embed/ephy-about-handler.c              |  125 +++++---
 embed/ephy-about-handler.h              |    1 +
 embed/ephy-embed-private.h              |    3 -
 embed/ephy-embed-shell.c                |   99 +++---
 embed/ephy-embed-shell.h                |    6 +-
 embed/ephy-web-view.c                   |  131 ++++----
 embed/web-extension/ephy-web-overview.c |   35 ++-
 lib/ephy-snapshot-service.c             |  123 ++++----
 lib/ephy-snapshot-service.h             |    3 -
 lib/widgets/Makefile.am                 |    4 -
 lib/widgets/ephy-frecent-store.c        |  431 -----------------------
 lib/widgets/ephy-frecent-store.h        |   67 ----
 lib/widgets/ephy-overview-store.c       |  566 -------------------------------
 lib/widgets/ephy-overview-store.h       |  101 ------
 14 files changed, 292 insertions(+), 1403 deletions(-)
---
diff --git a/embed/ephy-about-handler.c b/embed/ephy-about-handler.c
index eeee07a..39151cb 100644
--- a/embed/ephy-about-handler.c
+++ b/embed/ephy-about-handler.c
@@ -24,7 +24,9 @@
 #include "ephy-embed-shell.h"
 #include "ephy-embed-prefs.h"
 #include "ephy-file-helpers.h"
+#include "ephy-history-service.h"
 #include "ephy-smaps.h"
+#include "ephy-snapshot-service.h"
 #include "ephy-web-app-utils.h"
 #include "ephy-embed-private.h"
 
@@ -397,64 +399,78 @@ ephy_about_handler_handle_applications (EphyAboutHandler *handler,
   return TRUE;
 }
 
-static GString *
-ephy_about_handler_generate_overview_html (EphyOverviewStore *store)
-{
-  GtkTreeIter iter;
-  GString *data_str;
-  char *row_url, *row_title;
-  char *row_snapshot;
-  char *thumbnail_style;
-  gboolean valid;
-
-  valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
-  data_str = g_string_new (NULL);
-
-  while (valid) {
-    gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
-      EPHY_OVERVIEW_STORE_URI, &row_url,
-      EPHY_OVERVIEW_STORE_TITLE, &row_title,
-      EPHY_OVERVIEW_STORE_SNAPSHOT_PATH, &row_snapshot,
-      -1);
+typedef struct {
+  char *url;
+  time_t mtime;
+} GetSnapshotPathAsyncData;
 
-    thumbnail_style = row_snapshot ? g_strdup_printf (" style=\"background: url(file://%s) no-repeat;\"", 
row_snapshot) : NULL;
-    g_free (row_snapshot);
+static void
+got_snapshot_path_for_url_cb (EphySnapshotService *service,
+                              GAsyncResult *result,
+                              GetSnapshotPathAsyncData *data)
+{
+  char *snapshot;
 
-    g_string_append_printf (data_str,
-      "<li>" \
-      "  <a class=\"overview-item\" title=\"%s\" href=\"%s\">" \
-      "    <div class=\"close-button\" onclick=\"removeFromOverview(this.parentNode,event)\" 
title=\"%s\">&#10006;</div>" \
-      "    <span class=\"thumbnail\"%s></span>" \
-      "    <span class=\"title\">%s</span>" \
-      "  </a>" \
-      "</li>",
-      g_markup_escape_text (row_title,-1), row_url, _("Remove from overview"),
-                            thumbnail_style ? thumbnail_style : "", row_title);
-
-    g_free (row_title);
-    g_free (row_url);
-    g_free (thumbnail_style);
-
-    valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter);
+  snapshot = ephy_snapshot_service_get_snapshot_path_for_url_finish (service, result, NULL);
+  if (snapshot) {
+    ephy_embed_shell_set_thumbanil_path (ephy_embed_shell_get_default (), data->url, data->mtime, snapshot);
+    g_free (snapshot);
   }
-  return data_str;
+  g_free (data->url);
+  g_free (data);
 }
 
-
-static gboolean
-ephy_about_handler_handle_html_overview (EphyAboutHandler *handler,
-                                        WebKitURISchemeRequest *request)
+static void
+history_service_query_urls_cb (EphyHistoryService *history,
+                               gboolean success,
+                               GList *urls,
+                               WebKitURISchemeRequest *request)
 {
   GString *data_str;
   GBytes *html_file;
   GString *html = g_string_new ("");
   gsize data_length;
-  EphyOverviewStore *store;
   char *lang;
+  GList *l;
+
+  data_str = g_string_new (NULL);
 
-  store = EPHY_OVERVIEW_STORE (ephy_embed_shell_get_frecent_store (ephy_embed_shell_get_default ()));
+  if (success) {
+    EphySnapshotService *snapshot_service = ephy_snapshot_service_get_default ();
+
+    for (l = urls; l; l = g_list_next (l)) {
+      EphyHistoryURL *url = (EphyHistoryURL *)l->data;
+      const char *snapshot;
+      char *thumbnail_style = NULL;
+
+      snapshot = ephy_snapshot_service_lookup_snapshot_path (snapshot_service, url->url);
+      if (!snapshot) {
+        GetSnapshotPathAsyncData *data = g_new (GetSnapshotPathAsyncData, 1);
+
+        data->url = g_strdup (url->url);
+        data->mtime = url->thumbnail_time;
+        ephy_snapshot_service_get_snapshot_path_for_url_async (ephy_snapshot_service_get_default (),
+                                                               url->url, url->thumbnail_time, NULL,
+                                                               
(GAsyncReadyCallback)got_snapshot_path_for_url_cb,
+                                                               data);
+      } else {
+        thumbnail_style = g_strdup_printf (" style=\"background: url(file://%s) no-repeat;\"", snapshot);
+      }
+
+      g_string_append_printf (data_str,
+                              "<li>"
+                              "  <a class=\"overview-item\" title=\"%s\" href=\"%s\">"
+                              "    <div class=\"close-button\" 
onclick=\"removeFromOverview(this.parentNode,event)\" title=\"%s\">&#10006;</div>"
+                              "    <span class=\"thumbnail\"%s></span>"
+                              "    <span class=\"title\">%s</span>"
+                              "  </a>"
+                              "</li>",
+                              g_markup_escape_text (url->title, -1), url->url, _("Remove from overview"),
+                              thumbnail_style ? thumbnail_style : "", url->title);
+      g_free (thumbnail_style);
+    }
+  }
 
-  data_str = ephy_about_handler_generate_overview_html(store);
   html_file = g_resources_lookup_data (EPHY_PAGE_TEMPLATE_OVERVIEW, 0, NULL);
 
   lang = g_strdup (pango_language_to_string (gtk_get_default_language ()));
@@ -469,10 +485,29 @@ ephy_about_handler_handle_html_overview (EphyAboutHandler *handler,
 
   data_length = html->len;
   ephy_about_handler_finish_request (request, g_string_free (html, FALSE), data_length);
+  g_object_unref (request);
 
   g_string_free (data_str,TRUE);
   g_bytes_unref (html_file);
   g_free (lang);
+}
+
+static gboolean
+ephy_about_handler_handle_html_overview (EphyAboutHandler *handler,
+                                         WebKitURISchemeRequest *request)
+{
+  EphyHistoryService *history;
+  EphyHistoryQuery *query;
+
+  history = EPHY_HISTORY_SERVICE (ephy_embed_shell_get_global_history_service (ephy_embed_shell_get_default 
()));
+  query = ephy_history_query_new ();
+  query->sort_type = EPHY_HISTORY_SORT_MOST_VISITED;
+  query->limit = EPHY_ABOUT_OVERVIEW_MAX_ITEMS;
+  query->ignore_hidden = TRUE;
+  ephy_history_service_query_urls (history, query, NULL,
+                                   (EphyHistoryJobCallback)history_service_query_urls_cb,
+                                   g_object_ref (request));
+  ephy_history_query_free (query);
 
   return TRUE;
 }
diff --git a/embed/ephy-about-handler.h b/embed/ephy-about-handler.h
index ae4fdb8..bcc6158 100644
--- a/embed/ephy-about-handler.h
+++ b/embed/ephy-about-handler.h
@@ -34,6 +34,7 @@ G_BEGIN_DECLS
 
 #define EPHY_ABOUT_SCHEME "ephy-about"
 #define EPHY_ABOUT_SCHEME_LEN 10
+#define EPHY_ABOUT_OVERVIEW_MAX_ITEMS 10
 
 typedef struct _EphyAboutHandlerClass   EphyAboutHandlerClass;
 typedef struct _EphyAboutHandler        EphyAboutHandler;
diff --git a/embed/ephy-embed-private.h b/embed/ephy-embed-private.h
index 5500b82..890f791 100644
--- a/embed/ephy-embed-private.h
+++ b/embed/ephy-embed-private.h
@@ -23,7 +23,6 @@
 #endif
 
 #include "ephy-embed-shell.h"
-#include "ephy-frecent-store.h"
 #include "ephy-history-types.h"
 #include "ephy-web-view.h"
 
@@ -61,8 +60,6 @@ void                       ephy_web_view_load_homepage            (EphyWebView
 char *                     ephy_web_view_create_web_application   (EphyWebView               *view,
                                                                    const char                *title,
                                                                    GdkPixbuf                 *icon);
-EphyFrecentStore          *ephy_embed_shell_get_frecent_store      (EphyEmbedShell *shell);
-
 G_END_DECLS
 
 #endif
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 99bc61d..618d901 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -54,8 +54,9 @@ struct _EphyEmbedShellPrivate
   GtkPageSetup *page_setup;
   GtkPrintSettings *print_settings;
   EphyEmbedShellMode mode;
-  EphyFrecentStore *frecent_store;
   EphyAboutHandler *about_handler;
+  guint update_overview_timeout_id;
+  guint hiding_overview_item;
   GDBusConnection *bus;
   GList *web_extensions;
   guint web_extensions_page_created_signal_id;
@@ -93,10 +94,14 @@ ephy_embed_shell_dispose (GObject *object)
 {
   EphyEmbedShellPrivate *priv = EPHY_EMBED_SHELL (object)->priv;
 
+  if (priv->update_overview_timeout_id > 0) {
+    g_source_remove (priv->update_overview_timeout_id);
+    priv->update_overview_timeout_id = 0;
+  }
+
   g_clear_object (&priv->encodings);
   g_clear_object (&priv->page_setup);
   g_clear_object (&priv->print_settings);
-  g_clear_object (&priv->frecent_store);
   g_clear_object (&priv->global_history_service);
   g_clear_object (&priv->about_handler);
 
@@ -188,7 +193,7 @@ ephy_embed_shell_update_overview_urls (EphyEmbedShell *shell)
 
   query = ephy_history_query_new ();
   query->sort_type = EPHY_HISTORY_SORT_MOST_VISITED;
-  query->limit = ephy_frecent_store_get_history_length (ephy_embed_shell_get_frecent_store (shell));
+  query->limit = EPHY_ABOUT_OVERVIEW_MAX_ITEMS;
   query->ignore_hidden = TRUE;
 
   ephy_history_service_query_urls (shell->priv->global_history_service, query, NULL,
@@ -205,10 +210,33 @@ history_service_urls_visited_cb (EphyHistoryService *history,
 }
 
 static gboolean
-ephy_embed_shell_update_overview (EphyEmbedShell *shell)
+ephy_embed_shell_update_overview_timeout_cb (EphyEmbedShell *shell)
 {
-    ephy_embed_shell_update_overview_urls (shell);
+  shell->priv->update_overview_timeout_id = 0;
+
+  if (shell->priv->hiding_overview_item > 0)
     return FALSE;
+
+  ephy_embed_shell_update_overview_urls (shell);
+
+  return FALSE;
+}
+
+static void
+history_set_url_hidden_cb (EphyHistoryService *service,
+                           gboolean success,
+                           gpointer result_data,
+                           EphyEmbedShell *shell)
+{
+  shell->priv->hiding_overview_item--;
+
+  if (!success)
+    return;
+
+  if (shell->priv->update_overview_timeout_id > 0)
+    return;
+
+  ephy_embed_shell_update_overview_urls (shell);
 }
 
 static void
@@ -220,20 +248,22 @@ web_extension_remove_from_overview (GDBusConnection *connection,
                                     GVariant *parameters,
                                     EphyEmbedShell *shell)
 {
-  GtkTreeIter iter;
-  EphyFrecentStore *store;
   const char *url_to_remove;
 
   g_variant_get (parameters, "(&s)", &url_to_remove);
-  store = ephy_embed_shell_get_frecent_store (shell);
 
-  if (ephy_overview_store_find_url (EPHY_OVERVIEW_STORE(store), url_to_remove, &iter)) {
-         ephy_frecent_store_set_hidden (store, &iter);
+  shell->priv->hiding_overview_item++;
+  ephy_history_service_set_url_hidden (shell->priv->global_history_service,
+                                       url_to_remove, TRUE, NULL,
+                                       (EphyHistoryJobCallback) history_set_url_hidden_cb,
+                                       shell);
 
-         /* Wait for the CSS animations to finish before refreshing */
-         g_timeout_add (OVERVIEW_RELOAD_DELAY, (GSourceFunc) ephy_embed_shell_update_overview, shell);
+  if (shell->priv->update_overview_timeout_id > 0)
+    g_source_remove (shell->priv->update_overview_timeout_id);
 
-  }
+  /* Wait for the CSS animations to finish before refreshing */
+  shell->priv->update_overview_timeout_id =
+    g_timeout_add (OVERVIEW_RELOAD_DELAY, (GSourceFunc) ephy_embed_shell_update_overview_timeout_cb, shell);
 }
 
 static void
@@ -328,14 +358,18 @@ history_service_cleared_cb (EphyHistoryService *service,
   }
 }
 
-static void
-frecent_store_snapshot_saved_cb (EphyOverviewStore *store,
-                                 const char *url,
-                                 const char *path,
-                                 EphyEmbedShell *shell)
+void
+ephy_embed_shell_set_thumbanil_path (EphyEmbedShell *shell,
+                                     const char *url,
+                                     time_t mtime,
+                                     const char *path)
 {
   GList *l;
 
+  ephy_history_service_set_url_thumbnail_time (shell->priv->global_history_service,
+                                               url, mtime,
+                                               NULL, NULL, NULL);
+
   for (l = shell->priv->web_extensions; l; l = g_list_next (l)) {
     EphyWebExtensionProxy *web_extension = (EphyWebExtensionProxy *)l->data;
 
@@ -376,41 +410,12 @@ ephy_embed_shell_get_global_history_service (EphyEmbedShell *shell)
     g_signal_connect (shell->priv->global_history_service, "cleared",
                       G_CALLBACK (history_service_cleared_cb),
                       shell);
-    g_signal_connect (ephy_embed_shell_get_frecent_store (shell), "snapshot-saved",
-                      G_CALLBACK (frecent_store_snapshot_saved_cb),
-                      shell);
   }
 
   return G_OBJECT (shell->priv->global_history_service);
 }
 
 /**
- * ephy_embed_shell_get_frecent_store:
- * @shell: a #EphyEmbedShell
- *
- * Gets the #EphyFrecentStore in the shell. This can be used
- * by EphyOverview implementors.
- *
- * Returns: (transfer none): a #EphyFrecentStore
- **/
-EphyFrecentStore *
-ephy_embed_shell_get_frecent_store (EphyEmbedShell *shell)
-{
-  g_return_val_if_fail (EPHY_IS_EMBED_SHELL (shell), NULL);
-
-  if (shell->priv->frecent_store == NULL) {
-    shell->priv->frecent_store = ephy_frecent_store_new ();
-    g_object_set (shell->priv->frecent_store,
-                  "history-service",
-                  ephy_embed_shell_get_global_history_service (shell),
-                  "history-length", 10,
-                  NULL);
-  }
-
-  return shell->priv->frecent_store;
-}
-
-/**
  * ephy_embed_shell_get_encodings:
  * @shell: the #EphyEmbedShell
  *
diff --git a/embed/ephy-embed-shell.h b/embed/ephy-embed-shell.h
index f488640..aa96de5 100644
--- a/embed/ephy-embed-shell.h
+++ b/embed/ephy-embed-shell.h
@@ -88,7 +88,11 @@ gboolean           ephy_embed_shell_launch_handler             (EphyEmbedShell
                                                                 GFile            *file,
                                                                 const char       *mime_type,
                                                                 guint32           user_time);
-void               ephy_embed_shell_clear_cache                (EphyEmbedShell *shell);
+void               ephy_embed_shell_clear_cache                (EphyEmbedShell   *shell);
+void               ephy_embed_shell_set_thumbanil_path         (EphyEmbedShell   *shell,
+                                                                const char       *url,
+                                                                time_t            mtime,
+                                                                const char       *path);
 
 G_END_DECLS
 
diff --git a/embed/ephy-web-view.c b/embed/ephy-web-view.c
index 5b7e780..649c727 100644
--- a/embed/ephy-web-view.c
+++ b/embed/ephy-web-view.c
@@ -39,6 +39,7 @@
 #include "ephy-history-service.h"
 #include "ephy-prefs.h"
 #include "ephy-settings.h"
+#include "ephy-snapshot-service.h"
 #include "ephy-string.h"
 #include "ephy-web-app-utils.h"
 #include "ephy-web-dom-utils.h"
@@ -100,7 +101,7 @@ struct _EphyWebViewPrivate {
   EphyHistoryService *history_service;
   GCancellable *history_service_cancellable;
 
-  guint snapshot_idle_id;
+  guint snapshot_timeout_id;
 
   EphyHistoryPageVisitType visit_type;
 
@@ -581,6 +582,50 @@ ephy_web_view_history_cleared_cb (EphyHistoryService *history_service,
   ephy_web_view_clear_history (view);
 }
 
+typedef struct {
+  char *url;
+  time_t mtime;
+} GetSnapshotPathAsyncData;
+
+static void
+got_snapshot_path_cb (EphySnapshotService *service,
+                      GAsyncResult *result,
+                      GetSnapshotPathAsyncData *data)
+{
+  char *snapshot;
+
+  snapshot = ephy_snapshot_service_get_snapshot_path_finish (service, result, NULL);
+  if (snapshot) {
+    ephy_embed_shell_set_thumbanil_path (ephy_embed_shell_get_default (), data->url, data->mtime, snapshot);
+    g_free (snapshot);
+  }
+  g_free (data->url);
+  g_free (data);
+}
+
+static gboolean
+web_view_check_snapshot (WebKitWebView *web_view)
+{
+  EphyWebView* view = EPHY_WEB_VIEW (web_view);
+  EphySnapshotService *service = ephy_snapshot_service_get_default ();
+  const char *url = webkit_web_view_get_uri (web_view);
+  GetSnapshotPathAsyncData *data;
+
+  view->priv->snapshot_timeout_id = 0;
+
+  if (ephy_snapshot_service_lookup_snapshot_path (service, url))
+    return FALSE;
+
+  data = g_new (GetSnapshotPathAsyncData, 1);
+  data->url = g_strdup (url);
+  data->mtime = time (NULL);
+  ephy_snapshot_service_get_snapshot_path_async (service, web_view, data->mtime, NULL,
+                                                 (GAsyncReadyCallback)got_snapshot_path_cb,
+                                                 data);
+
+  return FALSE;
+}
+
 static void
 _ephy_web_view_update_icon (EphyWebView *view)
 {
@@ -605,6 +650,11 @@ icon_changed_cb (EphyWebView *view,
                  GParamSpec *pspec,
                  gpointer user_data)
 {
+  if (view->priv->snapshot_timeout_id == 0) {
+    view->priv->snapshot_timeout_id = g_timeout_add_full (G_PRIORITY_LOW, 0,
+                                                          (GSourceFunc)web_view_check_snapshot,
+                                                          view, NULL);
+  }
   _ephy_web_view_update_icon (view);
 }
 
@@ -694,9 +744,9 @@ ephy_web_view_dispose (GObject *object)
     g_clear_object (&priv->history_service_cancellable);
   }
 
-  if (priv->snapshot_idle_id) {
-    g_source_remove (priv->snapshot_idle_id);
-    priv->snapshot_idle_id = 0;
+  if (priv->snapshot_timeout_id) {
+    g_source_remove (priv->snapshot_timeout_id);
+    priv->snapshot_timeout_id = 0;
   }
 
   g_clear_object(&priv->certificate);
@@ -1505,58 +1555,6 @@ ephy_web_view_location_changed (EphyWebView *view,
 }
 
 static void
-on_snapshot_ready (WebKitWebView *webview,
-                   GAsyncResult *res,
-                   GtkTreeRowReference *ref)
-{
-  GtkTreeModel *model;
-  cairo_surface_t *surface;
-  GError *error = NULL;
-
-  surface = webkit_web_view_get_snapshot_finish (webview, res, &error);
-  if (error) {
-    g_warning ("%s(): %s", G_STRFUNC, error->message);
-    g_error_free (error);
-    return;
-  }
-
-  model = gtk_tree_row_reference_get_model (ref);
-  ephy_overview_store_set_snapshot (EPHY_OVERVIEW_STORE (model), ref, surface,
-                                    webkit_web_view_get_favicon (webview));
-  cairo_surface_destroy (surface);
-}
-
-/* FIXME: We should be using the snapshot service for this instead of
-   using the WK API directly. */
-static gboolean
-web_view_check_snapshot (WebKitWebView *web_view)
-{
-  EphyOverviewStore *store;
-  GtkTreeIter iter;
-  GtkTreeRowReference *ref;
-  GtkTreePath *path;
-  EphyWebView* view = EPHY_WEB_VIEW (web_view);
-
-  EphyEmbedShell *embed_shell = ephy_embed_shell_get_default ();
-
-  store = EPHY_OVERVIEW_STORE (ephy_embed_shell_get_frecent_store (embed_shell));
-  if (ephy_overview_store_find_url (store, webkit_web_view_get_uri (web_view), &iter) &&
-      ephy_overview_store_needs_snapshot (store, &iter)) {
-    path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
-    ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store), path);
-    gtk_tree_path_free (path);
-    webkit_web_view_get_snapshot (web_view, WEBKIT_SNAPSHOT_REGION_VISIBLE,
-                                  WEBKIT_SNAPSHOT_OPTIONS_NONE,
-                                  NULL, (GAsyncReadyCallback)on_snapshot_ready,
-                                  ref);
-  }
-
-  view->priv->snapshot_idle_id = 0;
-
-  return FALSE;
-}
-
-static void
 load_changed_cb (WebKitWebView *web_view,
                  WebKitLoadEvent load_event,
                  gpointer user_data)
@@ -1573,6 +1571,11 @@ load_changed_cb (WebKitWebView *web_view,
 
     priv->load_failed = FALSE;
 
+    if (priv->snapshot_timeout_id) {
+      g_source_remove (priv->snapshot_timeout_id);
+      priv->snapshot_timeout_id = 0;
+    }
+
     loading_uri = webkit_web_view_get_uri (web_view);
     g_signal_emit_by_name (view, "new-document-now", loading_uri);
 
@@ -1650,10 +1653,18 @@ load_changed_cb (WebKitWebView *web_view,
     /* Reset visit type. */
     priv->visit_type = EPHY_PAGE_VISIT_NONE;
 
-    if (!ephy_web_view_is_history_frozen (view)) {
-      if (priv->snapshot_idle_id)
-        g_source_remove (priv->snapshot_idle_id);
-      priv->snapshot_idle_id = g_idle_add_full (G_PRIORITY_LOW, (GSourceFunc)web_view_check_snapshot, 
web_view, NULL);
+    if (!ephy_web_view_is_history_frozen (view) &&
+        ephy_embed_shell_get_mode (ephy_embed_shell_get_default ()) != EPHY_EMBED_SHELL_MODE_INCOGNITO) {
+      if (!ephy_snapshot_service_lookup_snapshot_path (ephy_snapshot_service_get_default (), 
webkit_web_view_get_uri (web_view))) {
+        /* If the snapshot check hasn't been scheduled already by the favicon callback,
+         * check the snapshot if we don't get a favicon in 1 second
+         */
+        if (priv->snapshot_timeout_id == 0) {
+          priv->snapshot_timeout_id = g_timeout_add_seconds_full (G_PRIORITY_LOW, 1,
+                                                                  (GSourceFunc)web_view_check_snapshot,
+                                                                  web_view, NULL);
+        }
+      }
     }
 
     ephy_web_view_thaw_history (view);
diff --git a/embed/web-extension/ephy-web-overview.c b/embed/web-extension/ephy-web-overview.c
index 27262e7..b72d222 100644
--- a/embed/web-extension/ephy-web-overview.c
+++ b/embed/web-extension/ephy-web-overview.c
@@ -119,6 +119,17 @@ ephy_web_overview_web_page_uri_changed (WebKitWebPage *web_page,
 }
 
 static void
+update_thumbnail_element_style (WebKitDOMElement *thumbnail,
+                                const char *path)
+{
+  char *style;
+
+  style = g_strdup_printf ("background: url(file://%s) no-repeat;", path);
+  webkit_dom_element_set_attribute (thumbnail, "style", style, NULL);
+  g_free (style);
+}
+
+static void
 ephy_web_overview_model_urls_changed (EphyWebOverviewModel *model,
                                       EphyWebOverview *overview)
 {
@@ -192,13 +203,8 @@ ephy_web_overview_model_urls_changed (EphyWebOverviewModel *model,
       new_node = WEBKIT_DOM_NODE (webkit_dom_document_create_element (document, "SPAN", NULL));
       item->thumbnail = g_object_ref (new_node);
       webkit_dom_element_set_class_name (WEBKIT_DOM_ELEMENT (new_node), "thumbnail");
-      if (thumbnail_path) {
-        char *style;
-
-        style = g_strdup_printf ("background: url(file://%s) no-repeat;", thumbnail_path);
-        webkit_dom_element_set_attribute (WEBKIT_DOM_ELEMENT (new_node), "style", style, NULL);
-        g_free (style);
-      }
+      if (thumbnail_path)
+        update_thumbnail_element_style (WEBKIT_DOM_ELEMENT (new_node), thumbnail_path);
       webkit_dom_node_append_child (WEBKIT_DOM_NODE (anchor), new_node, NULL);
 
       new_node = WEBKIT_DOM_NODE (webkit_dom_document_create_element (document, "SPAN", NULL));
@@ -239,14 +245,9 @@ ephy_web_overview_model_thumbnail_changed (EphyWebOverviewModel *model,
 
   for (l = overview->priv->items; l; l = g_list_next (l)) {
     OverviewItem *item = (OverviewItem *)l->data;
-    char *style;
-
-    if (g_strcmp0 (item->url, url) != 0)
-      continue;
 
-    style = g_strdup_printf ("background: url(file://%s) no-repeat;", path);
-    webkit_dom_element_set_attribute (item->thumbnail, "style", style, NULL);
-    g_free (style);
+    if (g_strcmp0 (item->url, url) == 0)
+      update_thumbnail_element_style (item->thumbnail, path);
   }
 }
 
@@ -299,7 +300,13 @@ ephy_web_overview_update_thumbnail_in_model_from_element (EphyWebOverview *overv
       g_signal_handlers_unblock_by_func (overview->priv->model, G_CALLBACK 
(ephy_web_overview_model_thumbnail_changed), overview);
       g_free (thumbnail_path);
     }
+  } else {
+    const char *path;
 
+    /* Check whether the model was updated while the overview was loading */
+    path = ephy_web_overview_model_get_url_thumbnail (overview->priv->model, url);
+    if (path)
+      update_thumbnail_element_style (thumbnail, path);
   }
   g_free (background);
 }
diff --git a/lib/ephy-snapshot-service.c b/lib/ephy-snapshot-service.c
index c0cb8db..4cb9230 100644
--- a/lib/ephy-snapshot-service.c
+++ b/lib/ephy-snapshot-service.c
@@ -159,6 +159,68 @@ snapshot_async_data_free (SnapshotAsyncData *data)
   g_slice_free (SnapshotAsyncData, data);
 }
 
+static GdkPixbuf *
+ephy_snapshot_service_prepare_snapshot (cairo_surface_t *surface,
+                                        cairo_surface_t *favicon)
+{
+  GdkPixbuf *snapshot, *scaled;
+  int orig_width, orig_height;
+  float orig_aspect_ratio, dest_aspect_ratio;
+  int x_offset, new_width = 0, new_height;
+
+  orig_width = cairo_image_surface_get_width (surface);
+  orig_height = cairo_image_surface_get_height (surface);
+
+  if (orig_width < EPHY_THUMBNAIL_WIDTH ||
+      orig_height < EPHY_THUMBNAIL_HEIGHT) {
+    snapshot = gdk_pixbuf_get_from_surface (surface,
+                                            0, 0,
+                                            orig_width, orig_height);
+    scaled = gdk_pixbuf_scale_simple (snapshot,
+                                      EPHY_THUMBNAIL_WIDTH,
+                                      EPHY_THUMBNAIL_HEIGHT,
+                                      GDK_INTERP_TILES);
+  } else {
+    orig_aspect_ratio = orig_width / (float)orig_height;
+    dest_aspect_ratio = EPHY_THUMBNAIL_WIDTH / (float)EPHY_THUMBNAIL_HEIGHT;
+
+    if (orig_aspect_ratio > dest_aspect_ratio) {
+      /* Wider than taller, crop the sides. */
+      new_width = orig_height * dest_aspect_ratio;
+      new_height = orig_height;
+      x_offset = (orig_width - new_width) / 2;
+    } else {
+      /* Crop the bottom otherwise. */
+      new_width = orig_width;
+      new_height = orig_width / (float)dest_aspect_ratio;
+      x_offset = 0;
+    }
+
+    snapshot = gdk_pixbuf_get_from_surface (surface, x_offset, 0, new_width, new_height);
+    scaled = gnome_desktop_thumbnail_scale_down_pixbuf (snapshot,
+                                                        EPHY_THUMBNAIL_WIDTH,
+                                                        EPHY_THUMBNAIL_HEIGHT);
+  }
+
+  g_object_unref (snapshot);
+
+  if (favicon) {
+    GdkPixbuf* fav_pixbuf;
+    int favicon_size = 16;
+    int x_offset = 6;
+    int y_offset = gdk_pixbuf_get_height (scaled) - favicon_size - x_offset;
+
+    fav_pixbuf = ephy_pixbuf_get_from_surface_scaled (favicon, favicon_size, favicon_size);
+    gdk_pixbuf_composite (fav_pixbuf, scaled,
+                          x_offset, y_offset, favicon_size, favicon_size,
+                          x_offset, y_offset, 1, 1,
+                          GDK_INTERP_NEAREST, 255);
+    g_object_unref (fav_pixbuf);
+  }
+
+  return scaled;
+}
+
 static void
 snapshot_saved (EphySnapshotService *service,
                 GAsyncResult *result,
@@ -588,67 +650,6 @@ ephy_snapshot_service_save_snapshot_finish (EphySnapshotService *service,
   return retval;
 }
 
-GdkPixbuf *
-ephy_snapshot_service_prepare_snapshot (cairo_surface_t *surface,
-                                        cairo_surface_t *favicon)
-{
-  GdkPixbuf *snapshot, *scaled;
-  int orig_width, orig_height;
-  float orig_aspect_ratio, dest_aspect_ratio;
-  int x_offset, new_width = 0, new_height;
-
-  orig_width = cairo_image_surface_get_width (surface);
-  orig_height = cairo_image_surface_get_height (surface);
-
-  if (orig_width < EPHY_THUMBNAIL_WIDTH ||
-      orig_height < EPHY_THUMBNAIL_HEIGHT) {
-    snapshot = gdk_pixbuf_get_from_surface (surface,
-                                            0, 0,
-                                            orig_width, orig_height);
-    scaled = gdk_pixbuf_scale_simple (snapshot,
-                                      EPHY_THUMBNAIL_WIDTH,
-                                      EPHY_THUMBNAIL_HEIGHT,
-                                      GDK_INTERP_TILES);
-  } else {
-    orig_aspect_ratio = orig_width / (float)orig_height;
-    dest_aspect_ratio = EPHY_THUMBNAIL_WIDTH / (float)EPHY_THUMBNAIL_HEIGHT;
-
-    if (orig_aspect_ratio > dest_aspect_ratio) {
-      /* Wider than taller, crop the sides. */
-      new_width = orig_height * dest_aspect_ratio;
-      new_height = orig_height;
-      x_offset = (orig_width - new_width) / 2;
-    } else {
-      /* Crop the bottom otherwise. */
-      new_width = orig_width;
-      new_height = orig_width / (float)dest_aspect_ratio;
-      x_offset = 0;
-    }
-
-    snapshot = gdk_pixbuf_get_from_surface (surface, x_offset, 0, new_width, new_height);
-    scaled = gnome_desktop_thumbnail_scale_down_pixbuf (snapshot,
-                                                        EPHY_THUMBNAIL_WIDTH,
-                                                        EPHY_THUMBNAIL_HEIGHT);
-  }
-
-  g_object_unref (snapshot);
-
-  if (favicon) {
-    GdkPixbuf* fav_pixbuf;
-    int favicon_size = 16;
-    int x_offset = 6;
-    int y_offset = gdk_pixbuf_get_height (scaled) - favicon_size - x_offset;
-    fav_pixbuf = ephy_pixbuf_get_from_surface_scaled (favicon, favicon_size, favicon_size);
-    gdk_pixbuf_composite (fav_pixbuf, scaled,
-                          x_offset, y_offset, favicon_size, favicon_size,
-                          x_offset, y_offset, 1, 1,
-                          GDK_INTERP_NEAREST, 255);
-    g_object_unref (fav_pixbuf);
-  }
-
-  return scaled;
-}
-
 const char *
 ephy_snapshot_service_lookup_snapshot_path (EphySnapshotService *service,
                                             const char *url)
diff --git a/lib/ephy-snapshot-service.h b/lib/ephy-snapshot-service.h
index dc62557..0484b79 100644
--- a/lib/ephy-snapshot-service.h
+++ b/lib/ephy-snapshot-service.h
@@ -105,9 +105,6 @@ char                *ephy_snapshot_service_save_snapshot_finish        (EphySnap
                                                                         GAsyncResult *result,
                                                                         GError **error);
 
-GdkPixbuf           *ephy_snapshot_service_prepare_snapshot            (cairo_surface_t *surface,
-                                                                        cairo_surface_t *favicon);
-
 const char          *ephy_snapshot_service_lookup_snapshot_path        (EphySnapshotService *service,
                                                                         const char *url);
 
diff --git a/lib/widgets/Makefile.am b/lib/widgets/Makefile.am
index b5a2109..247cd9a 100644
--- a/lib/widgets/Makefile.am
+++ b/lib/widgets/Makefile.am
@@ -67,16 +67,12 @@ libephywidgets_la_SOURCES = \
        ephy-certificate-dialog.h               \
        ephy-download-widget.c                  \
        ephy-download-widget.h                  \
-       ephy-frecent-store.c                    \
-       ephy-frecent-store.h                    \
        ephy-location-entry.c                   \
        ephy-location-entry.h                   \
        ephy-middle-clickable-button.c          \
        ephy-middle-clickable-button.h          \
        ephy-node-view.c                        \
        ephy-node-view.h                        \
-       ephy-overview-store.c                   \
-       ephy-overview-store.h                   \
        ephy-tree-model-node.c                  \
        ephy-tree-model-node.h                  \
        ephy-tree-model-sort.c                  \


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]