Bug 588050 - Cache information icon forever, only look up recent once
Extend ShellTextureCache by adding the concept of a policy, which we expose to the public API for loading URIs. This lets us have the shell tell the cache to keep the information icon texture around forever. Secondly, fix the caching of recent info; we shouldn't always be loading the backup pixbuf. Move recent info loading entirely into ShellTextureCache.
This commit is contained in:
parent
2c5d520395
commit
8d9fc28872
@ -24,19 +24,7 @@ DocInfo.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
createIcon : function(size) {
|
createIcon : function(size) {
|
||||||
let icon = null;
|
return Shell.TextureCache.get_default().load_recent_thumbnail(size, this._recentInfo);
|
||||||
let defaultPixbuf = this._recentInfo.get_icon(size);
|
|
||||||
|
|
||||||
if (this.uri.match("^file://")) {
|
|
||||||
icon = Shell.TextureCache.get_default().load_thumbnail(size, this.uri, this.mimeType,
|
|
||||||
defaultPixbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!icon) {
|
|
||||||
icon = new Clutter.Texture({});
|
|
||||||
Shell.clutter_texture_set_from_pixbuf(icon, defaultPixbuf);
|
|
||||||
}
|
|
||||||
return icon;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
launch : function() {
|
launch : function() {
|
||||||
@ -137,13 +125,13 @@ DocManager.prototype = {
|
|||||||
let deleted = {};
|
let deleted = {};
|
||||||
for (var uri in this._items) {
|
for (var uri in this._items) {
|
||||||
if (!(uri in newItems))
|
if (!(uri in newItems))
|
||||||
deleted[uri] = 1;
|
deleted[uri] = this._items[uri];
|
||||||
}
|
}
|
||||||
/* If we'd cached any thumbnail references that no longer exist,
|
/* If we'd cached any thumbnail references that no longer exist,
|
||||||
dump them here */
|
dump them here */
|
||||||
let texCache = Shell.TextureCache.get_default();
|
let texCache = Shell.TextureCache.get_default();
|
||||||
for (var uri in deleted) {
|
for (var uri in deleted) {
|
||||||
texCache.unref_thumbnail(this._iconSize, uri);
|
texCache.evict_recent_thumbnail(this._iconSize, this._items[uri]);
|
||||||
}
|
}
|
||||||
this._items = newItems;
|
this._items = newItems;
|
||||||
},
|
},
|
||||||
|
@ -58,7 +58,8 @@ DocDisplayItem.prototype = {
|
|||||||
if (this._docInfo.mimeType == null || this._docInfo.mimeType.indexOf("image/") != 0)
|
if (this._docInfo.mimeType == null || this._docInfo.mimeType.indexOf("image/") != 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return Shell.TextureCache.get_default().load_uri_sync(this._docInfo.uri, availableWidth, availableHeight);
|
return Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.NONE,
|
||||||
|
this._docInfo.uri, availableWidth, availableHeight);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -85,7 +85,8 @@ GenericDisplayItem.prototype = {
|
|||||||
|
|
||||||
let global = Shell.Global.get();
|
let global = Shell.Global.get();
|
||||||
let infoIconUri = "file://" + global.imagedir + "info.svg";
|
let infoIconUri = "file://" + global.imagedir + "info.svg";
|
||||||
let infoIcon = Shell.TextureCache.get_default().load_uri_sync(infoIconUri,
|
let infoIcon = Shell.TextureCache.get_default().load_uri_sync(Shell.TextureCachePolicy.FOREVER,
|
||||||
|
infoIconUri,
|
||||||
INFORMATION_BUTTON_SIZE,
|
INFORMATION_BUTTON_SIZE,
|
||||||
INFORMATION_BUTTON_SIZE);
|
INFORMATION_BUTTON_SIZE);
|
||||||
this._informationButton = new Button.iconButton(this.actor, INFORMATION_BUTTON_SIZE, infoIcon);
|
this._informationButton = new Button.iconButton(this.actor, INFORMATION_BUTTON_SIZE, infoIcon);
|
||||||
|
@ -6,14 +6,20 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
ShellTextureCachePolicy policy;
|
||||||
|
|
||||||
|
/* These 3 are exclusive */
|
||||||
GIcon *icon;
|
GIcon *icon;
|
||||||
|
gchar *uri;
|
||||||
gchar *thumbnail_uri;
|
gchar *thumbnail_uri;
|
||||||
|
|
||||||
|
/* This one is common to all 3 */
|
||||||
guint size;
|
guint size;
|
||||||
} CacheKey;
|
} CacheKey;
|
||||||
|
|
||||||
struct _ShellTextureCachePrivate
|
struct _ShellTextureCachePrivate
|
||||||
{
|
{
|
||||||
GHashTable *gicon_cache; /* CacheKey -> CoglTexture* */
|
GHashTable *keyed_cache; /* CacheKey -> CoglTexture* */
|
||||||
GnomeThumbnailFactory *thumbnails;
|
GnomeThumbnailFactory *thumbnails;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -29,6 +35,8 @@ cache_key_hash (gconstpointer a)
|
|||||||
|
|
||||||
if (akey->icon)
|
if (akey->icon)
|
||||||
return g_icon_hash (akey->icon) + 31*akey->size;
|
return g_icon_hash (akey->icon) + 31*akey->size;
|
||||||
|
else if (akey->uri)
|
||||||
|
return g_str_hash (akey->uri) + 31*akey->size;
|
||||||
else if (akey->thumbnail_uri)
|
else if (akey->thumbnail_uri)
|
||||||
return g_str_hash (akey->thumbnail_uri) + 31*akey->size;
|
return g_str_hash (akey->thumbnail_uri) + 31*akey->size;
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
@ -41,23 +49,43 @@ cache_key_equal (gconstpointer a,
|
|||||||
CacheKey *akey = (CacheKey*)a;
|
CacheKey *akey = (CacheKey*)a;
|
||||||
CacheKey *bkey = (CacheKey*)b;
|
CacheKey *bkey = (CacheKey*)b;
|
||||||
|
|
||||||
|
/* We don't compare policy here, since we need
|
||||||
|
* a way to look up a cache key without respect to
|
||||||
|
* the policy. */
|
||||||
|
|
||||||
if (akey->size != bkey->size)
|
if (akey->size != bkey->size)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (akey->icon && bkey->icon)
|
if (akey->icon && bkey->icon)
|
||||||
return g_icon_equal (akey->icon, bkey->icon);
|
return g_icon_equal (akey->icon, bkey->icon);
|
||||||
|
else if (akey->uri && bkey->uri)
|
||||||
|
return strcmp (akey->uri, bkey->uri) == 0;
|
||||||
else if (akey->thumbnail_uri && bkey->thumbnail_uri)
|
else if (akey->thumbnail_uri && bkey->thumbnail_uri)
|
||||||
return strcmp (akey->thumbnail_uri, bkey->thumbnail_uri) == 0;
|
return strcmp (akey->thumbnail_uri, bkey->thumbnail_uri) == 0;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CacheKey *
|
||||||
|
cache_key_dup (CacheKey *key)
|
||||||
|
{
|
||||||
|
CacheKey *ret = g_new0 (CacheKey, 1);
|
||||||
|
ret->policy = key->policy;
|
||||||
|
if (key->icon)
|
||||||
|
ret->icon = g_object_ref (key->icon);
|
||||||
|
ret->uri = g_strdup (key->uri);
|
||||||
|
ret->thumbnail_uri = g_strdup (key->thumbnail_uri);
|
||||||
|
ret->size = key->size;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cache_key_destroy (gpointer a)
|
cache_key_destroy (gpointer a)
|
||||||
{
|
{
|
||||||
CacheKey *akey = (CacheKey*)a;
|
CacheKey *akey = (CacheKey*)a;
|
||||||
if (akey->icon)
|
if (akey->icon)
|
||||||
g_object_unref (akey->icon);
|
g_object_unref (akey->icon);
|
||||||
if (akey->thumbnail_uri)
|
g_free (akey->uri);
|
||||||
g_free (akey->thumbnail_uri);
|
g_free (akey->thumbnail_uri);
|
||||||
g_free (akey);
|
g_free (akey);
|
||||||
}
|
}
|
||||||
@ -75,7 +103,7 @@ static void
|
|||||||
shell_texture_cache_init (ShellTextureCache *self)
|
shell_texture_cache_init (ShellTextureCache *self)
|
||||||
{
|
{
|
||||||
self->priv = g_new0 (ShellTextureCachePrivate, 1);
|
self->priv = g_new0 (ShellTextureCachePrivate, 1);
|
||||||
self->priv->gicon_cache = g_hash_table_new_full (cache_key_hash, cache_key_equal,
|
self->priv->keyed_cache = g_hash_table_new_full (cache_key_hash, cache_key_equal,
|
||||||
cache_key_destroy, cogl_handle_unref);
|
cache_key_destroy, cogl_handle_unref);
|
||||||
self->priv->thumbnails = gnome_thumbnail_factory_new (GNOME_THUMBNAIL_SIZE_NORMAL);
|
self->priv->thumbnails = gnome_thumbnail_factory_new (GNOME_THUMBNAIL_SIZE_NORMAL);
|
||||||
}
|
}
|
||||||
@ -85,9 +113,9 @@ shell_texture_cache_dispose (GObject *object)
|
|||||||
{
|
{
|
||||||
ShellTextureCache *self = (ShellTextureCache*)object;
|
ShellTextureCache *self = (ShellTextureCache*)object;
|
||||||
|
|
||||||
if (self->priv->gicon_cache)
|
if (self->priv->keyed_cache)
|
||||||
g_hash_table_destroy (self->priv->gicon_cache);
|
g_hash_table_destroy (self->priv->keyed_cache);
|
||||||
self->priv->gicon_cache = NULL;
|
self->priv->keyed_cache = NULL;
|
||||||
|
|
||||||
if (self->priv->thumbnails)
|
if (self->priv->thumbnails)
|
||||||
g_object_unref (self->priv->thumbnails);
|
g_object_unref (self->priv->thumbnails);
|
||||||
@ -113,9 +141,9 @@ typedef struct {
|
|||||||
ShellTextureCache *cache;
|
ShellTextureCache *cache;
|
||||||
char *uri;
|
char *uri;
|
||||||
char *mimetype;
|
char *mimetype;
|
||||||
GdkPixbuf *fallback_pixbuf;
|
|
||||||
gboolean thumbnail;
|
gboolean thumbnail;
|
||||||
GIcon *icon;
|
GIcon *icon;
|
||||||
|
GtkRecentInfo *recent_info;
|
||||||
GtkIconInfo *icon_info;
|
GtkIconInfo *icon_info;
|
||||||
gint width;
|
gint width;
|
||||||
gint height;
|
gint height;
|
||||||
@ -221,8 +249,8 @@ icon_lookup_data_destroy (gpointer p)
|
|||||||
g_free (data->uri);
|
g_free (data->uri);
|
||||||
if (data->mimetype)
|
if (data->mimetype)
|
||||||
g_free (data->mimetype);
|
g_free (data->mimetype);
|
||||||
if (data->fallback_pixbuf)
|
if (data->recent_info)
|
||||||
g_object_unref (data->fallback_pixbuf);
|
gtk_recent_info_unref (data->recent_info);
|
||||||
|
|
||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
@ -415,11 +443,23 @@ load_pixbuf_thread (GSimpleAsyncResult *result,
|
|||||||
|
|
||||||
if (data->thumbnail)
|
if (data->thumbnail)
|
||||||
{
|
{
|
||||||
pixbuf = impl_load_thumbnail (data->cache, data->uri, data->mimetype, data->width, &error);
|
const char *uri;
|
||||||
if (!pixbuf && data->fallback_pixbuf)
|
const char *mimetype;
|
||||||
|
|
||||||
|
if (data->recent_info)
|
||||||
{
|
{
|
||||||
g_clear_error (&error);
|
uri = gtk_recent_info_get_uri (data->recent_info);
|
||||||
pixbuf = g_object_ref (data->fallback_pixbuf);
|
mimetype = gtk_recent_info_get_mime_type (data->recent_info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uri = data->uri;
|
||||||
|
mimetype = data->mimetype;
|
||||||
|
}
|
||||||
|
pixbuf = impl_load_thumbnail (data->cache, uri, mimetype, data->width, &error);
|
||||||
|
if (!pixbuf && data->recent_info)
|
||||||
|
{
|
||||||
|
pixbuf = gtk_recent_info_get_icon (data->recent_info, data->width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (data->uri)
|
else if (data->uri)
|
||||||
@ -504,7 +544,6 @@ load_thumbnail_async (ShellTextureCache *cache,
|
|||||||
const char *uri,
|
const char *uri,
|
||||||
const char *mimetype,
|
const char *mimetype,
|
||||||
guint size,
|
guint size,
|
||||||
GdkPixbuf *fallback,
|
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GAsyncReadyCallback callback,
|
GAsyncReadyCallback callback,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
@ -516,7 +555,6 @@ load_thumbnail_async (ShellTextureCache *cache,
|
|||||||
data->cache = cache;
|
data->cache = cache;
|
||||||
data->uri = g_strdup (uri);
|
data->uri = g_strdup (uri);
|
||||||
data->mimetype = g_strdup (mimetype);
|
data->mimetype = g_strdup (mimetype);
|
||||||
data->fallback_pixbuf = g_object_ref (fallback);
|
|
||||||
data->thumbnail = TRUE;
|
data->thumbnail = TRUE;
|
||||||
data->width = size;
|
data->width = size;
|
||||||
data->height = size;
|
data->height = size;
|
||||||
@ -530,6 +568,33 @@ load_thumbnail_async (ShellTextureCache *cache,
|
|||||||
g_object_unref (result);
|
g_object_unref (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_recent_thumbnail_async (ShellTextureCache *cache,
|
||||||
|
GtkRecentInfo *info,
|
||||||
|
guint size,
|
||||||
|
GCancellable *cancellable,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GSimpleAsyncResult *result;
|
||||||
|
AsyncIconLookupData *data;
|
||||||
|
|
||||||
|
data = g_new0 (AsyncIconLookupData, 1);
|
||||||
|
data->cache = cache;
|
||||||
|
data->thumbnail = TRUE;
|
||||||
|
data->recent_info = gtk_recent_info_ref (info);
|
||||||
|
data->width = size;
|
||||||
|
data->height = size;
|
||||||
|
data->user_data = user_data;
|
||||||
|
|
||||||
|
result = g_simple_async_result_new (G_OBJECT (cache), callback, user_data, load_recent_thumbnail_async);
|
||||||
|
|
||||||
|
g_object_set_data_full (G_OBJECT (result), "load_pixbuf_async", data, icon_lookup_data_destroy);
|
||||||
|
g_simple_async_result_run_in_thread (result, load_pixbuf_thread, G_PRIORITY_DEFAULT, cancellable);
|
||||||
|
|
||||||
|
g_object_unref (result);
|
||||||
|
}
|
||||||
|
|
||||||
static GdkPixbuf *
|
static GdkPixbuf *
|
||||||
load_pixbuf_async_finish (ShellTextureCache *cache, GAsyncResult *result, GError **error)
|
load_pixbuf_async_finish (ShellTextureCache *cache, GAsyncResult *result, GError **error)
|
||||||
{
|
{
|
||||||
@ -540,9 +605,11 @@ load_pixbuf_async_finish (ShellTextureCache *cache, GAsyncResult *result, GError
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
ShellTextureCachePolicy policy;
|
||||||
char *uri;
|
char *uri;
|
||||||
gboolean thumbnail;
|
gboolean thumbnail;
|
||||||
char *mimetype;
|
char *mimetype;
|
||||||
|
GtkRecentInfo *recent_info;
|
||||||
GIcon *icon;
|
GIcon *icon;
|
||||||
GtkIconInfo *icon_info;
|
GtkIconInfo *icon_info;
|
||||||
guint width;
|
guint width;
|
||||||
@ -587,20 +654,25 @@ on_pixbuf_loaded (GObject *source,
|
|||||||
|
|
||||||
g_object_unref (pixbuf);
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
if (data->icon || data->thumbnail)
|
if (data->policy != SHELL_TEXTURE_CACHE_POLICY_NONE)
|
||||||
{
|
{
|
||||||
gpointer orig_key, value;
|
gpointer orig_key, value;
|
||||||
|
|
||||||
key = g_new0 (CacheKey, 1);
|
key = g_new0 (CacheKey, 1);
|
||||||
|
key->policy = data->policy;
|
||||||
if (data->icon)
|
if (data->icon)
|
||||||
key->icon = g_object_ref (data->icon);
|
key->icon = g_object_ref (data->icon);
|
||||||
else
|
else if (data->recent_info && data->thumbnail)
|
||||||
|
key->thumbnail_uri = g_strdup (gtk_recent_info_get_uri (data->recent_info));
|
||||||
|
else if (data->thumbnail)
|
||||||
key->thumbnail_uri = g_strdup (data->uri);
|
key->thumbnail_uri = g_strdup (data->uri);
|
||||||
|
else if (data->uri)
|
||||||
|
key->uri = g_strdup (data->uri);
|
||||||
key->size = data->width;
|
key->size = data->width;
|
||||||
|
|
||||||
if (!g_hash_table_lookup_extended (cache->priv->gicon_cache, key,
|
if (!g_hash_table_lookup_extended (cache->priv->keyed_cache, key,
|
||||||
&orig_key, &value))
|
&orig_key, &value))
|
||||||
g_hash_table_insert (cache->priv->gicon_cache, key,
|
g_hash_table_insert (cache->priv->keyed_cache, key,
|
||||||
texdata);
|
texdata);
|
||||||
else
|
else
|
||||||
cache_key_destroy (key);
|
cache_key_destroy (key);
|
||||||
@ -617,6 +689,8 @@ out:
|
|||||||
else if (data->uri)
|
else if (data->uri)
|
||||||
g_free (data->uri);
|
g_free (data->uri);
|
||||||
|
|
||||||
|
if (data->recent_info)
|
||||||
|
gtk_recent_info_unref (data->recent_info);
|
||||||
if (data->mimetype)
|
if (data->mimetype)
|
||||||
g_free (data->mimetype);
|
g_free (data->mimetype);
|
||||||
|
|
||||||
@ -651,7 +725,7 @@ shell_texture_cache_load_gicon (ShellTextureCache *cache,
|
|||||||
memset (&key, 0, sizeof(key));
|
memset (&key, 0, sizeof(key));
|
||||||
key.icon = icon;
|
key.icon = icon;
|
||||||
key.size = size;
|
key.size = size;
|
||||||
texdata = g_hash_table_lookup (cache->priv->gicon_cache, &key);
|
texdata = g_hash_table_lookup (cache->priv->keyed_cache, &key);
|
||||||
|
|
||||||
if (texdata == NULL)
|
if (texdata == NULL)
|
||||||
{
|
{
|
||||||
@ -666,7 +740,9 @@ shell_texture_cache_load_gicon (ShellTextureCache *cache,
|
|||||||
{
|
{
|
||||||
AsyncTextureLoadData *data;
|
AsyncTextureLoadData *data;
|
||||||
data = g_new0 (AsyncTextureLoadData, 1);
|
data = g_new0 (AsyncTextureLoadData, 1);
|
||||||
|
/* hardcoded here for now; we should actually blow this away on
|
||||||
|
* icon theme changes probably */
|
||||||
|
data->policy = SHELL_TEXTURE_CACHE_POLICY_FOREVER;
|
||||||
data->icon = g_object_ref (icon);
|
data->icon = g_object_ref (icon);
|
||||||
data->icon_info = info;
|
data->icon_info = info;
|
||||||
data->texture = g_object_ref (texture);
|
data->texture = g_object_ref (texture);
|
||||||
@ -708,6 +784,7 @@ shell_texture_cache_load_uri_async (ShellTextureCache *cache,
|
|||||||
texture = CLUTTER_TEXTURE (clutter_texture_new ());
|
texture = CLUTTER_TEXTURE (clutter_texture_new ());
|
||||||
|
|
||||||
data = g_new0 (AsyncTextureLoadData, 1);
|
data = g_new0 (AsyncTextureLoadData, 1);
|
||||||
|
data->policy = SHELL_TEXTURE_CACHE_POLICY_NONE;
|
||||||
data->uri = g_strdup (uri);
|
data->uri = g_strdup (uri);
|
||||||
data->width = available_width;
|
data->width = available_width;
|
||||||
data->height = available_height;
|
data->height = available_height;
|
||||||
@ -721,6 +798,7 @@ shell_texture_cache_load_uri_async (ShellTextureCache *cache,
|
|||||||
* shell_texture_cache_load_uri_sync:
|
* shell_texture_cache_load_uri_sync:
|
||||||
*
|
*
|
||||||
* @cache: The texture cache instance
|
* @cache: The texture cache instance
|
||||||
|
* @policy: Requested lifecycle of cached data
|
||||||
* @uri: uri of the image file from which to create a pixbuf
|
* @uri: uri of the image file from which to create a pixbuf
|
||||||
* @available_width: available width for the image, can be -1 if not limited
|
* @available_width: available width for the image, can be -1 if not limited
|
||||||
* @available_height: available height for the image, can be -1 if not limited
|
* @available_height: available height for the image, can be -1 if not limited
|
||||||
@ -736,22 +814,47 @@ shell_texture_cache_load_uri_async (ShellTextureCache *cache,
|
|||||||
*/
|
*/
|
||||||
ClutterActor *
|
ClutterActor *
|
||||||
shell_texture_cache_load_uri_sync (ShellTextureCache *cache,
|
shell_texture_cache_load_uri_sync (ShellTextureCache *cache,
|
||||||
|
ShellTextureCachePolicy policy,
|
||||||
const gchar *uri,
|
const gchar *uri,
|
||||||
int available_width,
|
int available_width,
|
||||||
int available_height,
|
int available_height,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
ClutterTexture *texture;
|
ClutterTexture *texture;
|
||||||
GdkPixbuf *pixbuf;
|
|
||||||
CoglHandle texdata;
|
CoglHandle texdata;
|
||||||
|
GdkPixbuf *pixbuf;
|
||||||
pixbuf = impl_load_pixbuf_file (uri, available_width, available_height, error);
|
CacheKey key;
|
||||||
if (!pixbuf)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
texture = CLUTTER_TEXTURE (clutter_texture_new ());
|
texture = CLUTTER_TEXTURE (clutter_texture_new ());
|
||||||
|
|
||||||
|
memset (&key, 0, sizeof (CacheKey));
|
||||||
|
key.policy = policy;
|
||||||
|
key.uri = (char*)uri;
|
||||||
|
key.size = available_width;
|
||||||
|
texdata = g_hash_table_lookup (cache->priv->keyed_cache, &key);
|
||||||
|
|
||||||
|
if (texdata == NULL)
|
||||||
|
{
|
||||||
|
pixbuf = impl_load_pixbuf_file (uri, available_width, available_height, error);
|
||||||
|
if (!pixbuf)
|
||||||
|
{
|
||||||
|
g_object_unref (texture);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
texdata = pixbuf_to_cogl_handle (pixbuf);
|
texdata = pixbuf_to_cogl_handle (pixbuf);
|
||||||
g_object_unref (pixbuf);
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
|
if (policy == SHELL_TEXTURE_CACHE_POLICY_FOREVER)
|
||||||
|
{
|
||||||
|
g_hash_table_insert (cache->priv->keyed_cache, cache_key_dup (&key), texdata);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cogl_handle_unref (texdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
clutter_texture_set_cogl_texture (texture, texdata);
|
clutter_texture_set_cogl_texture (texture, texdata);
|
||||||
|
|
||||||
return CLUTTER_ACTOR (texture);
|
return CLUTTER_ACTOR (texture);
|
||||||
@ -763,7 +866,6 @@ shell_texture_cache_load_uri_sync (ShellTextureCache *cache,
|
|||||||
* @size: Size in pixels to use for thumbnail
|
* @size: Size in pixels to use for thumbnail
|
||||||
* @uri: Source URI
|
* @uri: Source URI
|
||||||
* @mimetype: Source mime type
|
* @mimetype: Source mime type
|
||||||
* @fallback: (allow-none): If no thumbnail is cached, use this pixbuf
|
|
||||||
*
|
*
|
||||||
* Asynchronously load a thumbnail image of a URI into a texture. The
|
* Asynchronously load a thumbnail image of a URI into a texture. The
|
||||||
* returned texture object will be a new instance; however, its texture data
|
* returned texture object will be a new instance; however, its texture data
|
||||||
@ -772,17 +874,13 @@ shell_texture_cache_load_uri_sync (ShellTextureCache *cache,
|
|||||||
* The current caching policy is permanent; to uncache, you must explicitly
|
* The current caching policy is permanent; to uncache, you must explicitly
|
||||||
* call shell_texture_cache_unref_thumbnail().
|
* call shell_texture_cache_unref_thumbnail().
|
||||||
*
|
*
|
||||||
* A fallback pixbuf may be provided in the case where thumbnailing is
|
|
||||||
* not applicable, or fails.
|
|
||||||
*
|
|
||||||
* Returns: (transfer none): A new #ClutterActor
|
* Returns: (transfer none): A new #ClutterActor
|
||||||
*/
|
*/
|
||||||
ClutterActor *
|
ClutterActor *
|
||||||
shell_texture_cache_load_thumbnail (ShellTextureCache *cache,
|
shell_texture_cache_load_thumbnail (ShellTextureCache *cache,
|
||||||
int size,
|
int size,
|
||||||
const char *uri,
|
const char *uri,
|
||||||
const char *mimetype,
|
const char *mimetype)
|
||||||
GdkPixbuf *fallback)
|
|
||||||
{
|
{
|
||||||
ClutterTexture *texture;
|
ClutterTexture *texture;
|
||||||
AsyncTextureLoadData *data;
|
AsyncTextureLoadData *data;
|
||||||
@ -796,17 +894,102 @@ shell_texture_cache_load_thumbnail (ShellTextureCache *cache,
|
|||||||
key.size = size;
|
key.size = size;
|
||||||
key.thumbnail_uri = (char*)uri;
|
key.thumbnail_uri = (char*)uri;
|
||||||
|
|
||||||
texdata = g_hash_table_lookup (cache->priv->gicon_cache, &key);
|
texdata = g_hash_table_lookup (cache->priv->keyed_cache, &key);
|
||||||
if (!texdata)
|
if (!texdata)
|
||||||
{
|
{
|
||||||
data = g_new0 (AsyncTextureLoadData, 1);
|
data = g_new0 (AsyncTextureLoadData, 1);
|
||||||
|
data->policy = SHELL_TEXTURE_CACHE_POLICY_FOREVER;
|
||||||
data->uri = g_strdup (uri);
|
data->uri = g_strdup (uri);
|
||||||
data->mimetype = g_strdup (mimetype);
|
data->mimetype = g_strdup (mimetype);
|
||||||
data->thumbnail = TRUE;
|
data->thumbnail = TRUE;
|
||||||
data->width = size;
|
data->width = size;
|
||||||
data->height = size;
|
data->height = size;
|
||||||
data->texture = g_object_ref (texture);
|
data->texture = g_object_ref (texture);
|
||||||
load_thumbnail_async (cache, uri, mimetype, size, fallback, NULL, on_pixbuf_loaded, data);
|
load_thumbnail_async (cache, uri, mimetype, size, NULL, on_pixbuf_loaded, data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clutter_texture_set_cogl_texture (texture, texdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CLUTTER_ACTOR (texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GIcon *
|
||||||
|
icon_for_recent (GtkRecentInfo *info)
|
||||||
|
{
|
||||||
|
const char *mimetype;
|
||||||
|
char *content_type;
|
||||||
|
GIcon *icon;
|
||||||
|
|
||||||
|
mimetype = gtk_recent_info_get_mime_type (info);
|
||||||
|
if (!mimetype)
|
||||||
|
{
|
||||||
|
return g_themed_icon_new (GTK_STOCK_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
content_type = g_content_type_from_mime_type (mimetype);
|
||||||
|
if (!content_type)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
icon = g_content_type_get_icon (content_type);
|
||||||
|
g_free (content_type);
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_texture_cache_load_recent_thumbnail:
|
||||||
|
* @cache:
|
||||||
|
* @size: Size in pixels to use for thumbnail
|
||||||
|
* @info: Recent item info
|
||||||
|
*
|
||||||
|
* Asynchronously load a thumbnail image of a #GtkRecentInfo into a texture. The
|
||||||
|
* returned texture object will be a new instance; however, its texture data
|
||||||
|
* may be shared with other objects. This implies the texture data is cached.
|
||||||
|
*
|
||||||
|
* The current caching policy is permanent; to uncache, you must explicitly
|
||||||
|
* call shell_texture_cache_unref_recent_thumbnail().
|
||||||
|
*
|
||||||
|
* Returns: (transfer none): A new #ClutterActor
|
||||||
|
*/
|
||||||
|
ClutterActor *
|
||||||
|
shell_texture_cache_load_recent_thumbnail (ShellTextureCache *cache,
|
||||||
|
int size,
|
||||||
|
GtkRecentInfo *info)
|
||||||
|
{
|
||||||
|
ClutterTexture *texture;
|
||||||
|
AsyncTextureLoadData *data;
|
||||||
|
CacheKey key;
|
||||||
|
CoglHandle texdata;
|
||||||
|
const char *uri;
|
||||||
|
|
||||||
|
uri = gtk_recent_info_get_uri (info);
|
||||||
|
|
||||||
|
/* Don't attempt to load thumbnails for non-local URIs */
|
||||||
|
if (!g_str_has_prefix (uri, "file://"))
|
||||||
|
{
|
||||||
|
GIcon *icon = icon_for_recent (info);
|
||||||
|
return shell_texture_cache_load_gicon (cache, icon, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
texture = CLUTTER_TEXTURE (clutter_texture_new ());
|
||||||
|
clutter_actor_set_size (CLUTTER_ACTOR (texture), size, size);
|
||||||
|
|
||||||
|
memset (&key, 0, sizeof(key));
|
||||||
|
key.size = size;
|
||||||
|
key.thumbnail_uri = (char*)gtk_recent_info_get_uri (info);
|
||||||
|
|
||||||
|
texdata = g_hash_table_lookup (cache->priv->keyed_cache, &key);
|
||||||
|
if (!texdata)
|
||||||
|
{
|
||||||
|
data = g_new0 (AsyncTextureLoadData, 1);
|
||||||
|
data->policy = SHELL_TEXTURE_CACHE_POLICY_FOREVER;
|
||||||
|
data->thumbnail = TRUE;
|
||||||
|
data->recent_info = gtk_recent_info_ref (info);
|
||||||
|
data->width = size;
|
||||||
|
data->height = size;
|
||||||
|
data->texture = g_object_ref (texture);
|
||||||
|
load_recent_thumbnail_async (cache, info, size, NULL, on_pixbuf_loaded, data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -817,7 +1000,7 @@ shell_texture_cache_load_thumbnail (ShellTextureCache *cache,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shell_texture_cache_unref_thumbnail:
|
* shell_texture_cache_evict_thumbnail:
|
||||||
* @cache:
|
* @cache:
|
||||||
* @size: Size in pixels
|
* @size: Size in pixels
|
||||||
* @uri: Source URI
|
* @uri: Source URI
|
||||||
@ -836,7 +1019,30 @@ shell_texture_cache_unref_thumbnail (ShellTextureCache *cache,
|
|||||||
key.size = size;
|
key.size = size;
|
||||||
key.thumbnail_uri = (char*)uri;
|
key.thumbnail_uri = (char*)uri;
|
||||||
|
|
||||||
g_hash_table_remove (cache->priv->gicon_cache, &key);
|
g_hash_table_remove (cache->priv->keyed_cache, &key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_texture_cache_evict_recent_thumbnail:
|
||||||
|
* @cache:
|
||||||
|
* @size: Size in pixels
|
||||||
|
* @info: A recent info
|
||||||
|
*
|
||||||
|
* Removes the reference the shell_texture_cache_load_recent_thumbnail() function
|
||||||
|
* created for a thumbnail.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
shell_texture_cache_evict_recent_thumbnail (ShellTextureCache *cache,
|
||||||
|
int size,
|
||||||
|
GtkRecentInfo *info)
|
||||||
|
{
|
||||||
|
CacheKey key;
|
||||||
|
|
||||||
|
memset (&key, 0, sizeof(key));
|
||||||
|
key.size = size;
|
||||||
|
key.thumbnail_uri = (char*)gtk_recent_info_get_uri (info);
|
||||||
|
|
||||||
|
g_hash_table_remove (cache->priv->keyed_cache, &key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ShellTextureCache *instance = NULL;
|
static ShellTextureCache *instance = NULL;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define __SHELL_TEXTURE_CACHE_H__
|
#define __SHELL_TEXTURE_CACHE_H__
|
||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
|
|
||||||
@ -30,6 +31,11 @@ struct _ShellTextureCacheClass
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SHELL_TEXTURE_CACHE_POLICY_NONE,
|
||||||
|
SHELL_TEXTURE_CACHE_POLICY_FOREVER
|
||||||
|
} ShellTextureCachePolicy;
|
||||||
|
|
||||||
GType shell_texture_cache_get_type (void) G_GNUC_CONST;
|
GType shell_texture_cache_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
ShellTextureCache* shell_texture_cache_get_default();
|
ShellTextureCache* shell_texture_cache_get_default();
|
||||||
@ -41,19 +47,27 @@ ClutterActor *shell_texture_cache_load_gicon (ShellTextureCache *cache,
|
|||||||
ClutterActor *shell_texture_cache_load_thumbnail (ShellTextureCache *cache,
|
ClutterActor *shell_texture_cache_load_thumbnail (ShellTextureCache *cache,
|
||||||
int size,
|
int size,
|
||||||
const char *uri,
|
const char *uri,
|
||||||
const char *mimetype,
|
const char *mimetype);
|
||||||
GdkPixbuf *fallback);
|
|
||||||
|
|
||||||
void shell_texture_cache_unref_thumbnail (ShellTextureCache *cache,
|
ClutterActor *shell_texture_cache_load_recent_thumbnail (ShellTextureCache *cache,
|
||||||
|
int size,
|
||||||
|
GtkRecentInfo *info);
|
||||||
|
|
||||||
|
void shell_texture_cache_evict_thumbnail (ShellTextureCache *cache,
|
||||||
int size,
|
int size,
|
||||||
const char *uri);
|
const char *uri);
|
||||||
|
|
||||||
|
void shell_texture_cache_evict_recent_thumbnail (ShellTextureCache *cache,
|
||||||
|
int size,
|
||||||
|
GtkRecentInfo *info);
|
||||||
|
|
||||||
ClutterActor *shell_texture_cache_load_uri_async (ShellTextureCache *cache,
|
ClutterActor *shell_texture_cache_load_uri_async (ShellTextureCache *cache,
|
||||||
const gchar *filename,
|
const gchar *filename,
|
||||||
int available_width,
|
int available_width,
|
||||||
int available_height);
|
int available_height);
|
||||||
|
|
||||||
ClutterActor *shell_texture_cache_load_uri_sync (ShellTextureCache *cache,
|
ClutterActor *shell_texture_cache_load_uri_sync (ShellTextureCache *cache,
|
||||||
|
ShellTextureCachePolicy policy,
|
||||||
const gchar *filename,
|
const gchar *filename,
|
||||||
int available_width,
|
int available_width,
|
||||||
int available_height,
|
int available_height,
|
||||||
|
Loading…
Reference in New Issue
Block a user