[gnome-shell] st-texture-cache: Add texture-file-changed signal
- From: Florian MÃllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] st-texture-cache: Add texture-file-changed signal
- Date: Wed, 17 Oct 2012 21:58:39 +0000 (UTC)
commit 9c8b75206c086b90558a3ba751203d9cd4757f3f
Author: Florian MÃllner <fmuellner gnome org>
Date: Thu Sep 20 21:42:52 2012 +0200
st-texture-cache: Add texture-file-changed signal
For textures loaded from files, the cache might hide image changes
by keeping the data of a previous version around indefinitely. For
instance AccountsService will notify of avatar changes, but as new
image is copied over the old one, we will continue to use the old
image data.
Install a file monitor for each file resource we load and clear
the corresponding data from the cache on changes, emitting the
new StTextureCache::texture-file-changed signal.
https://bugzilla.gnome.org/show_bug.cgi?id=679268
src/st/st-texture-cache.c | 77 ++++++++++++++++++++++++++++++++++++++++----
1 files changed, 70 insertions(+), 7 deletions(-)
---
diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c
index 0508006..2ba0f8e 100644
--- a/src/st/st-texture-cache.c
+++ b/src/st/st-texture-cache.c
@@ -42,6 +42,9 @@ struct _StTextureCachePrivate
/* Presently this is used to de-duplicate requests for GIcons and async URIs. */
GHashTable *outstanding_requests; /* char * -> AsyncTextureLoadData * */
+
+ /* File monitors to evict cache data on changes */
+ GHashTable *file_monitors; /* char * -> GFileMonitor * */
};
static void st_texture_cache_dispose (GObject *object);
@@ -50,6 +53,7 @@ static void st_texture_cache_finalize (GObject *object);
enum
{
ICON_THEME_CHANGED,
+ TEXTURE_FILE_CHANGED,
LAST_SIGNAL
};
@@ -92,6 +96,14 @@ st_texture_cache_class_init (StTextureCacheClass *klass)
0, /* no default handler slot */
NULL, NULL, NULL,
G_TYPE_NONE, 0);
+
+ signals[TEXTURE_FILE_CHANGED] =
+ g_signal_new ("texture-file-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, /* no default handler slot */
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
}
/**
@@ -164,6 +176,9 @@ st_texture_cache_init (StTextureCache *self)
g_free, cogl_handle_unref);
self->priv->outstanding_requests = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL);
+ self->priv->file_monitors = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_object_unref, g_object_unref);
+
}
static void
@@ -179,13 +194,9 @@ st_texture_cache_dispose (GObject *object)
self->priv->icon_theme = NULL;
}
- if (self->priv->keyed_cache)
- g_hash_table_destroy (self->priv->keyed_cache);
- self->priv->keyed_cache = NULL;
-
- if (self->priv->outstanding_requests)
- g_hash_table_destroy (self->priv->outstanding_requests);
- self->priv->outstanding_requests = NULL;
+ g_clear_pointer (&self->priv->keyed_cache, g_hash_table_destroy);
+ g_clear_pointer (&self->priv->outstanding_requests, g_hash_table_destroy);
+ g_clear_pointer (&self->priv->file_monitors, g_hash_table_destroy);
G_OBJECT_CLASS (st_texture_cache_parent_class)->dispose (object);
}
@@ -1039,6 +1050,52 @@ load_from_pixbuf (GdkPixbuf *pixbuf)
return CLUTTER_ACTOR (texture);
}
+static void
+file_changed_cb (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ StTextureCache *cache = user_data;
+ char *uri, *key;
+
+ if (event_type != G_FILE_MONITOR_EVENT_CHANGED)
+ return;
+
+ uri = g_file_get_uri (file);
+
+ key = g_strconcat (CACHE_PREFIX_URI, uri, NULL);
+ g_hash_table_remove (cache->priv->keyed_cache, key);
+ g_free (key);
+
+ key = g_strconcat (CACHE_PREFIX_URI_FOR_CAIRO, uri, NULL);
+ g_hash_table_remove (cache->priv->keyed_cache, key);
+ g_free (key);
+
+ g_signal_emit (cache, signals[TEXTURE_FILE_CHANGED], 0, uri);
+
+ g_free (uri);
+}
+
+static void
+ensure_monitor_for_uri (StTextureCache *cache,
+ const gchar *uri)
+{
+ StTextureCachePrivate *priv = cache->priv;
+ GFile *file = g_file_new_for_uri (uri);
+
+ if (g_hash_table_lookup (priv->file_monitors, uri) == NULL)
+ {
+ GFileMonitor *monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE,
+ NULL, NULL);
+ g_signal_connect (monitor, "changed",
+ G_CALLBACK (file_changed_cb), cache);
+ g_hash_table_insert (priv->file_monitors, g_strdup (uri), monitor);
+ }
+ g_object_unref (file);
+}
+
typedef struct {
gchar *path;
gint grid_width, grid_height;
@@ -1211,6 +1268,8 @@ st_texture_cache_load_uri_async (StTextureCache *cache,
load_texture_async (cache, request);
}
+ ensure_monitor_for_uri (cache, uri);
+
return CLUTTER_ACTOR (texture);
}
@@ -1248,6 +1307,8 @@ st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache,
else
cogl_handle_ref (texdata);
+ ensure_monitor_for_uri (cache, uri);
+
out:
g_free (key);
return texdata;
@@ -1287,6 +1348,8 @@ st_texture_cache_load_uri_sync_to_cairo_surface (StTextureCache *cache,
else
cairo_surface_reference (surface);
+ ensure_monitor_for_uri (cache, uri);
+
out:
g_free (key);
return surface;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]