aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2022-06-04 15:06:10 +0200
committerPřemysl Eric Janouch <p@janouch.name>2022-06-04 16:37:25 +0200
commite2adac72cc15e47b2aa47c1bea07c61a60c547d7 (patch)
tree7501ded27e719fb1bc1e857361c6d46ac65ecb3f
parent3ddb0cf20568b84e053b1608d22d55657e8ce5dd (diff)
downloadfiv-e2adac72cc15e47b2aa47c1bea07c61a60c547d7.tar.gz
fiv-e2adac72cc15e47b2aa47c1bea07c61a60c547d7.tar.xz
fiv-e2adac72cc15e47b2aa47c1bea07c61a60c547d7.zip
Use the model's mtime for validating thumbnails
Saves a syscall, generalizes fiv_thumbnail_lookup(), wastes a tiny bit of memory per entry.
-rw-r--r--fiv-browser.c15
-rw-r--r--fiv-io.h4
-rw-r--r--fiv-thumbnail.c14
-rw-r--r--fiv-thumbnail.h3
4 files changed, 15 insertions, 21 deletions
diff --git a/fiv-browser.c b/fiv-browser.c
index 69f5dff..56d5692 100644
--- a/fiv-browser.c
+++ b/fiv-browser.c
@@ -86,6 +86,7 @@ struct _FivBrowser {
struct entry {
char *uri; ///< GIO URI
+ gint64 mtime_msec; ///< Modification time in milliseconds
cairo_surface_t *thumbnail; ///< Prescaled thumbnail
GIcon *icon; ///< If no thumbnail, use this icon
};
@@ -427,18 +428,20 @@ entry_add_thumbnail(gpointer data, gpointer user_data)
g_clear_pointer(&self->thumbnail, cairo_surface_destroy);
FivBrowser *browser = FIV_BROWSER(user_data);
- GFile *file = g_file_new_for_uri(self->uri);
self->thumbnail = rescale_thumbnail(
- fiv_thumbnail_lookup(file, browser->item_size), browser->item_height);
+ fiv_thumbnail_lookup(self->uri, self->mtime_msec, browser->item_size),
+ browser->item_height);
if (self->thumbnail)
- goto out;
+ return;
// Fall back to symbolic icons, though there's only so much we can do
// in parallel--GTK+ isn't thread-safe.
+ GFile *file = g_file_new_for_uri(self->uri);
GFileInfo *info = g_file_query_info(file,
G_FILE_ATTRIBUTE_STANDARD_NAME
"," G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON,
G_FILE_QUERY_INFO_NONE, NULL, NULL);
+ g_object_unref(file);
if (info) {
GIcon *icon = g_file_info_get_symbolic_icon(info);
if (icon)
@@ -449,8 +452,6 @@ entry_add_thumbnail(gpointer data, gpointer user_data)
// The GVfs backend may not be friendly.
if (!self->icon)
self->icon = g_icon_new_for_string("text-x-generic-symbolic", NULL);
-out:
- g_object_unref(file);
}
static void
@@ -1707,8 +1708,8 @@ on_model_files_changed(FivIoModel *model, FivBrowser *self)
gsize len = 0;
const FivIoModelEntry *files = fiv_io_model_get_files(self->model, &len);
for (gsize i = 0; i < len; i++) {
- g_array_append_val(self->entries,
- ((Entry) {.thumbnail = NULL, .uri = g_strdup(files[i].uri)}));
+ g_array_append_val(self->entries, ((Entry) {.thumbnail = NULL,
+ .uri = g_strdup(files[i].uri), .mtime_msec = files[i].mtime_msec}));
}
fiv_browser_select(self, selected_uri);
diff --git a/fiv-io.h b/fiv-io.h
index ed25d67..5a3ba27 100644
--- a/fiv-io.h
+++ b/fiv-io.h
@@ -123,8 +123,8 @@ gboolean fiv_io_model_open(FivIoModel *self, GFile *directory, GError **error);
GFile *fiv_io_model_get_location(FivIoModel *self);
typedef struct {
- gchar *uri; ///< GIO URI
- gchar *collate_key; ///< Collate key for the filename
+ char *uri; ///< GIO URI
+ char *collate_key; ///< Collate key for the filename
gint64 mtime_msec; ///< Modification time in milliseconds
} FivIoModelEntry;
diff --git a/fiv-thumbnail.c b/fiv-thumbnail.c
index d1d67c4..2dfd15f 100644
--- a/fiv-thumbnail.c
+++ b/fiv-thumbnail.c
@@ -579,18 +579,11 @@ fail_init:
}
cairo_surface_t *
-fiv_thumbnail_lookup(GFile *target, FivThumbnailSize size)
+fiv_thumbnail_lookup(char *uri, gint64 mtime_msec, FivThumbnailSize size)
{
g_return_val_if_fail(size >= FIV_THUMBNAIL_SIZE_MIN &&
size <= FIV_THUMBNAIL_SIZE_MAX, NULL);
- // Local files only, at least for now.
- GStatBuf st = {};
- const gchar *path = g_file_peek_path(target);
- if (!path || g_stat(path, &st))
- return NULL;
-
- gchar *uri = g_file_get_uri(target);
gchar *sum = g_compute_checksum_for_string(G_CHECKSUM_MD5, uri, -1);
gchar *thumbnails_dir = fiv_thumbnail_get_root();
@@ -605,7 +598,7 @@ fiv_thumbnail_lookup(GFile *target, FivThumbnailSize size)
const char *name = fiv_thumbnail_sizes[use].thumbnail_spec_name;
gchar *wide =
g_strdup_printf("%s/wide-%s/%s.webp", thumbnails_dir, name, sum);
- result = read_wide_thumbnail(wide, uri, st.st_mtim.tv_sec, &error);
+ result = read_wide_thumbnail(wide, uri, mtime_msec / 1000, &error);
if (error) {
g_debug("%s: %s", wide, error->message);
g_clear_error(&error);
@@ -621,7 +614,7 @@ fiv_thumbnail_lookup(GFile *target, FivThumbnailSize size)
gchar *path =
g_strdup_printf("%s/%s/%s.png", thumbnails_dir, name, sum);
- result = read_spng_thumbnail(path, uri, st.st_mtim.tv_sec, &error);
+ result = read_spng_thumbnail(path, uri, mtime_msec / 1000, &error);
if (error) {
g_debug("%s: %s", path, error->message);
g_clear_error(&error);
@@ -639,7 +632,6 @@ fiv_thumbnail_lookup(GFile *target, FivThumbnailSize size)
g_free(thumbnails_dir);
g_free(sum);
- g_free(uri);
return result;
}
diff --git a/fiv-thumbnail.h b/fiv-thumbnail.h
index 101e8a8..822e609 100644
--- a/fiv-thumbnail.h
+++ b/fiv-thumbnail.h
@@ -62,7 +62,8 @@ gboolean fiv_thumbnail_produce(GFile *target, FivThumbnailSize max_size,
/// Retrieves a thumbnail of the most appropriate quality and resolution
/// for the target file.
-cairo_surface_t *fiv_thumbnail_lookup(GFile *target, FivThumbnailSize size);
+cairo_surface_t *fiv_thumbnail_lookup(
+ char *uri, gint64 mtime_msec, FivThumbnailSize size);
/// Invalidate the wide thumbnail cache. May write to standard streams.
void fiv_thumbnail_invalidate(void);