aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fiv-browser.c51
1 files changed, 39 insertions, 12 deletions
diff --git a/fiv-browser.c b/fiv-browser.c
index 111c291..10cb17a 100644
--- a/fiv-browser.c
+++ b/fiv-browser.c
@@ -439,6 +439,9 @@ entry_add_thumbnail(gpointer data, gpointer user_data)
(intptr_t) cairo_surface_get_user_data(
cached, &fiv_browser_key_mtime_msec) == self->mtime_msec) {
self->thumbnail = cairo_surface_reference(cached);
+ // TODO(p): If this hit is low-quality, see if a high-quality thumbnail
+ // hasn't been produced without our knowledge (avoid launching a minion
+ // unnecessarily; we might also shift the concern there).
} else {
cairo_surface_t *found = fiv_thumbnail_lookup(
self->uri, self->mtime_msec, browser->item_size);
@@ -555,19 +558,31 @@ thumbnailer_reprocess_entry(FivBrowser *self, GBytes *output, Entry *entry)
{
g_clear_object(&entry->icon);
g_clear_pointer(&entry->thumbnail, cairo_surface_destroy);
- guint64 dummy;
+
+ gtk_widget_queue_resize(GTK_WIDGET(self));
+
+ guint64 flags = 0;
if (!output || !(entry->thumbnail = rescale_thumbnail(
- fiv_io_deserialize(output, &dummy), self->item_height))) {
+ fiv_io_deserialize(output, &flags), self->item_height))) {
entry_add_thumbnail(entry, self);
materialize_icon(self, entry);
- } else {
- // This choice of mtime favours unnecessary thumbnail reloading.
- cairo_surface_set_user_data(entry->thumbnail,
- &fiv_browser_key_mtime_msec, (void *) (intptr_t) entry->mtime_msec,
- NULL);
+ return;
}
+ if ((flags & FIV_IO_SERIALIZE_LOW_QUALITY)) {
+ cairo_surface_set_user_data(entry->thumbnail, &fiv_thumbnail_key_lq,
+ (void *) (intptr_t) 1, NULL);
- gtk_widget_queue_resize(GTK_WIDGET(self));
+ // TODO(p): Improve complexity; this will iterate the whole linked list.
+ self->thumbnailers_queue =
+ g_list_append(self->thumbnailers_queue, entry);
+ }
+
+ // This choice of mtime favours unnecessary thumbnail reloading.
+ cairo_surface_set_user_data(entry->thumbnail,
+ &fiv_browser_key_mtime_msec, (void *) (intptr_t) entry->mtime_msec,
+ NULL);
+ g_hash_table_insert(self->thumbnail_cache, g_strdup(entry->uri),
+ cairo_surface_reference(entry->thumbnail));
}
static void
@@ -629,11 +644,23 @@ thumbnailer_next(Thumbnailer *t)
self->thumbnailers_queue =
g_list_delete_link(self->thumbnailers_queue, self->thumbnailers_queue);
+ // Case analysis:
+ // - We haven't found any thumbnail for the entry at all
+ // (and it has a symbolic icon as a result):
+ // we want to fill the void ASAP, so go for embedded thumbnails first.
+ // - We've found one, but we're not quite happy with it:
+ // always run the full process for a high-quality wide thumbnail.
+ // - We can't end up here in any other cases.
+ const char *argv_faster[] = {PROJECT_NAME, "--extract-thumbnail",
+ "--thumbnail", fiv_thumbnail_sizes[self->item_size].thumbnail_spec_name,
+ "--", t->target->uri, NULL};
+ const char *argv_slower[] = {PROJECT_NAME,
+ "--thumbnail", fiv_thumbnail_sizes[self->item_size].thumbnail_spec_name,
+ "--", t->target->uri, NULL};
+
GError *error = NULL;
- t->minion = g_subprocess_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE, &error,
- PROJECT_NAME, "--thumbnail",
- fiv_thumbnail_sizes[self->item_size].thumbnail_spec_name, "--",
- t->target->uri, NULL);
+ t->minion = g_subprocess_newv(t->target->icon ? argv_faster : argv_slower,
+ G_SUBPROCESS_FLAGS_STDOUT_PIPE, &error);
if (error) {
g_warning("%s", error->message);
g_error_free(error);