Use the model's mtime for validating thumbnails
Saves a syscall, generalizes fiv_thumbnail_lookup(), wastes a tiny bit of memory per entry.
This commit is contained in:
parent
3ddb0cf205
commit
e2adac72cc
|
@ -86,6 +86,7 @@ struct _FivBrowser {
|
||||||
|
|
||||||
struct entry {
|
struct entry {
|
||||||
char *uri; ///< GIO URI
|
char *uri; ///< GIO URI
|
||||||
|
gint64 mtime_msec; ///< Modification time in milliseconds
|
||||||
cairo_surface_t *thumbnail; ///< Prescaled thumbnail
|
cairo_surface_t *thumbnail; ///< Prescaled thumbnail
|
||||||
GIcon *icon; ///< If no thumbnail, use this icon
|
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);
|
g_clear_pointer(&self->thumbnail, cairo_surface_destroy);
|
||||||
|
|
||||||
FivBrowser *browser = FIV_BROWSER(user_data);
|
FivBrowser *browser = FIV_BROWSER(user_data);
|
||||||
GFile *file = g_file_new_for_uri(self->uri);
|
|
||||||
self->thumbnail = rescale_thumbnail(
|
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)
|
if (self->thumbnail)
|
||||||
goto out;
|
return;
|
||||||
|
|
||||||
// Fall back to symbolic icons, though there's only so much we can do
|
// Fall back to symbolic icons, though there's only so much we can do
|
||||||
// in parallel--GTK+ isn't thread-safe.
|
// in parallel--GTK+ isn't thread-safe.
|
||||||
|
GFile *file = g_file_new_for_uri(self->uri);
|
||||||
GFileInfo *info = g_file_query_info(file,
|
GFileInfo *info = g_file_query_info(file,
|
||||||
G_FILE_ATTRIBUTE_STANDARD_NAME
|
G_FILE_ATTRIBUTE_STANDARD_NAME
|
||||||
"," G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON,
|
"," G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON,
|
||||||
G_FILE_QUERY_INFO_NONE, NULL, NULL);
|
G_FILE_QUERY_INFO_NONE, NULL, NULL);
|
||||||
|
g_object_unref(file);
|
||||||
if (info) {
|
if (info) {
|
||||||
GIcon *icon = g_file_info_get_symbolic_icon(info);
|
GIcon *icon = g_file_info_get_symbolic_icon(info);
|
||||||
if (icon)
|
if (icon)
|
||||||
|
@ -449,8 +452,6 @@ entry_add_thumbnail(gpointer data, gpointer user_data)
|
||||||
// The GVfs backend may not be friendly.
|
// The GVfs backend may not be friendly.
|
||||||
if (!self->icon)
|
if (!self->icon)
|
||||||
self->icon = g_icon_new_for_string("text-x-generic-symbolic", NULL);
|
self->icon = g_icon_new_for_string("text-x-generic-symbolic", NULL);
|
||||||
out:
|
|
||||||
g_object_unref(file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1707,8 +1708,8 @@ on_model_files_changed(FivIoModel *model, FivBrowser *self)
|
||||||
gsize len = 0;
|
gsize len = 0;
|
||||||
const FivIoModelEntry *files = fiv_io_model_get_files(self->model, &len);
|
const FivIoModelEntry *files = fiv_io_model_get_files(self->model, &len);
|
||||||
for (gsize i = 0; i < len; i++) {
|
for (gsize i = 0; i < len; i++) {
|
||||||
g_array_append_val(self->entries,
|
g_array_append_val(self->entries, ((Entry) {.thumbnail = NULL,
|
||||||
((Entry) {.thumbnail = NULL, .uri = g_strdup(files[i].uri)}));
|
.uri = g_strdup(files[i].uri), .mtime_msec = files[i].mtime_msec}));
|
||||||
}
|
}
|
||||||
|
|
||||||
fiv_browser_select(self, selected_uri);
|
fiv_browser_select(self, selected_uri);
|
||||||
|
|
4
fiv-io.h
4
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);
|
GFile *fiv_io_model_get_location(FivIoModel *self);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
gchar *uri; ///< GIO URI
|
char *uri; ///< GIO URI
|
||||||
gchar *collate_key; ///< Collate key for the filename
|
char *collate_key; ///< Collate key for the filename
|
||||||
gint64 mtime_msec; ///< Modification time in milliseconds
|
gint64 mtime_msec; ///< Modification time in milliseconds
|
||||||
} FivIoModelEntry;
|
} FivIoModelEntry;
|
||||||
|
|
||||||
|
|
|
@ -579,18 +579,11 @@ fail_init:
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_surface_t *
|
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 &&
|
g_return_val_if_fail(size >= FIV_THUMBNAIL_SIZE_MIN &&
|
||||||
size <= FIV_THUMBNAIL_SIZE_MAX, NULL);
|
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 *sum = g_compute_checksum_for_string(G_CHECKSUM_MD5, uri, -1);
|
||||||
gchar *thumbnails_dir = fiv_thumbnail_get_root();
|
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;
|
const char *name = fiv_thumbnail_sizes[use].thumbnail_spec_name;
|
||||||
gchar *wide =
|
gchar *wide =
|
||||||
g_strdup_printf("%s/wide-%s/%s.webp", thumbnails_dir, name, sum);
|
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) {
|
if (error) {
|
||||||
g_debug("%s: %s", wide, error->message);
|
g_debug("%s: %s", wide, error->message);
|
||||||
g_clear_error(&error);
|
g_clear_error(&error);
|
||||||
|
@ -621,7 +614,7 @@ fiv_thumbnail_lookup(GFile *target, FivThumbnailSize size)
|
||||||
|
|
||||||
gchar *path =
|
gchar *path =
|
||||||
g_strdup_printf("%s/%s/%s.png", thumbnails_dir, name, sum);
|
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) {
|
if (error) {
|
||||||
g_debug("%s: %s", path, error->message);
|
g_debug("%s: %s", path, error->message);
|
||||||
g_clear_error(&error);
|
g_clear_error(&error);
|
||||||
|
@ -639,7 +632,6 @@ fiv_thumbnail_lookup(GFile *target, FivThumbnailSize size)
|
||||||
|
|
||||||
g_free(thumbnails_dir);
|
g_free(thumbnails_dir);
|
||||||
g_free(sum);
|
g_free(sum);
|
||||||
g_free(uri);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,8 @@ gboolean fiv_thumbnail_produce(GFile *target, FivThumbnailSize max_size,
|
||||||
|
|
||||||
/// Retrieves a thumbnail of the most appropriate quality and resolution
|
/// Retrieves a thumbnail of the most appropriate quality and resolution
|
||||||
/// for the target file.
|
/// 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.
|
/// Invalidate the wide thumbnail cache. May write to standard streams.
|
||||||
void fiv_thumbnail_invalidate(void);
|
void fiv_thumbnail_invalidate(void);
|
||||||
|
|
Loading…
Reference in New Issue