st: always use GFile internally

We're moving the theme infrastructure towards GResource, so as a first
step move all the loading to use GFiles instead of URIs or paths.

https://bugzilla.gnome.org/show_bug.cgi?id=736936
This commit is contained in:
Cosimo Cecchi 2014-09-18 17:04:00 -07:00 committed by Jasper St. Pierre
parent 38add2e78b
commit 328bb1c21b
18 changed files with 192 additions and 200 deletions

View File

@ -1,6 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter; const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const Lang = imports.lang; const Lang = imports.lang;
const Signals = imports.signals; const Signals = imports.signals;
const St = imports.gi.St; const St = imports.gi.St;
@ -126,7 +127,7 @@ const AuthPrompt = new Lang.Class({
this._initButtons(); this._initButtons();
let spinnerIcon = global.datadir + '/theme/process-working.svg'; let spinnerIcon = Gio.File.new_for_path(global.datadir + '/theme/process-working.svg');
this._spinner = new Animation.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE); this._spinner = new Animation.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE);
this._spinner.actor.opacity = 0; this._spinner.actor.opacity = 0;
this._spinner.actor.show(); this._spinner.actor.show();

View File

@ -537,24 +537,24 @@ const LoginDialog = new Lang.Class({
} }
}, },
_updateLogoTexture: function(cache, uri) { _updateLogoTexture: function(cache, file) {
if (this._logoFileUri != uri) if (!this._logoFile.equal(file))
return; return;
this._logoBin.destroy_all_children(); this._logoBin.destroy_all_children();
if (this._logoFileUri) { if (this._logoFile) {
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._logoBin.add_child(this._textureCache.load_uri_async(this._logoFileUri, this._logoBin.add_child(this._textureCache.load_file_async(this._logoFile,
-1, _LOGO_ICON_HEIGHT, -1, _LOGO_ICON_HEIGHT,
scaleFactor)); scaleFactor));
} }
}, },
_updateLogo: function() { _updateLogo: function() {
let path = this._settings.get_string(GdmUtil.LOGO_KEY); let path = this._settings.get_string(GdmUtil.LOGO_KEY);
this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; this._logoFile = path ? Gio.file_new_for_path(path) : null;
this._updateLogoTexture(this._textureCache, this._logoFileUri); this._updateLogoTexture(this._textureCache, this._logoFile);
}, },
_onPrompted: function() { _onPrompted: function() {

View File

@ -12,7 +12,7 @@ const ANIMATED_ICON_UPDATE_TIMEOUT = 100;
const Animation = new Lang.Class({ const Animation = new Lang.Class({
Name: 'Animation', Name: 'Animation',
_init: function(filename, width, height, speed) { _init: function(file, width, height, speed) {
this.actor = new St.Bin(); this.actor = new St.Bin();
this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
this._speed = speed; this._speed = speed;
@ -23,7 +23,7 @@ const Animation = new Lang.Class({
this._frame = 0; this._frame = 0;
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
this._animations = St.TextureCache.get_default().load_sliced_image (filename, width, height, scaleFactor, this._animations = St.TextureCache.get_default().load_sliced_image (file, width, height, scaleFactor,
Lang.bind(this, this._animationsLoaded)); Lang.bind(this, this._animationsLoaded));
this.actor.set_child(this._animations); this.actor.set_child(this._animations);
}, },
@ -82,7 +82,7 @@ const AnimatedIcon = new Lang.Class({
Name: 'AnimatedIcon', Name: 'AnimatedIcon',
Extends: Animation, Extends: Animation,
_init: function(filename, size) { _init: function(file, size) {
this.parent(filename, size, size, ANIMATED_ICON_UPDATE_TIMEOUT); this.parent(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
} }
}); });

View File

@ -1264,9 +1264,8 @@ const SubscriptionRequestNotification = new Lang.Class({
let file = contact.get_avatar_file(); let file = contact.get_avatar_file();
if (file) { if (file) {
let uri = file.get_uri();
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor; let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
iconBox.child = textureCache.load_uri_async(uri, iconBox._size, iconBox._size, scaleFactor); iconBox.child = textureCache.load_file_async(file, iconBox._size, iconBox._size, scaleFactor);
} }
else { else {
iconBox.child = new St.Icon({ icon_name: 'avatar-default', iconBox.child = new St.Icon({ icon_name: 'avatar-default',

View File

@ -194,7 +194,7 @@ const ModalDialog = new Lang.Class({
}, },
placeSpinner: function(layoutInfo) { placeSpinner: function(layoutInfo) {
let spinnerIcon = global.datadir + '/theme/process-working.svg'; let spinnerIcon = Gio.File.new_for_path(global.datadir + '/theme/process-working.svg');
this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE); this._workSpinner = new Animation.AnimatedIcon(spinnerIcon, WORK_SPINNER_ICON_SIZE);
this._workSpinner.actor.opacity = 0; this._workSpinner.actor.opacity = 0;
this._workSpinner.actor.show(); this._workSpinner.actor.show();

View File

@ -273,7 +273,7 @@ const AppMenuButton = new Lang.Class({
_onStyleChanged: function(actor) { _onStyleChanged: function(actor) {
let node = actor.get_theme_node(); let node = actor.get_theme_node();
let [success, icon] = node.lookup_url('spinner-image', false); let [success, icon] = node.lookup_url('spinner-image', false);
if (!success || this._spinnerIcon == icon) if (!success || (this._spinnerIcon && this._spinnerIcon.equal(icon)))
return; return;
this._spinnerIcon = icon; this._spinnerIcon = icon;
this._spinner = new Animation.AnimatedIcon(this._spinnerIcon, PANEL_ICON_SIZE); this._spinner = new Animation.AnimatedIcon(this._spinnerIcon, PANEL_ICON_SIZE);

View File

@ -876,7 +876,8 @@ const NMWirelessDialog = new Lang.Class({
x_align: Clutter.ActorAlign.CENTER, x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER }); y_align: Clutter.ActorAlign.CENTER });
this._noNetworksSpinner = new Animation.AnimatedIcon(global.datadir + '/theme/process-working.svg', 24, 24); let file = Gio.File.new_for_path(global.datadir + '/theme/process-working.svg');
this._noNetworksSpinner = new Animation.AnimatedIcon(file, 24, 24);
this._noNetworksBox.add_actor(this._noNetworksSpinner.actor); this._noNetworksBox.add_actor(this._noNetworksSpinner.actor);
this._noNetworksBox.add_actor(new St.Label({ style_class: 'no-networks-label', this._noNetworksBox.add_actor(new St.Label({ style_class: 'no-networks-label',
text: _("No Networks") })); text: _("No Networks") }));

View File

@ -27,7 +27,7 @@
struct _StBorderImage { struct _StBorderImage {
GObject parent; GObject parent;
char *filename; GFile *file;
int border_top; int border_top;
int border_right; int border_right;
int border_bottom; int border_bottom;
@ -48,7 +48,7 @@ st_border_image_finalize (GObject *object)
{ {
StBorderImage *image = ST_BORDER_IMAGE (object); StBorderImage *image = ST_BORDER_IMAGE (object);
g_free (image->filename); g_object_unref (image->file);
G_OBJECT_CLASS (st_border_image_parent_class)->finalize (object); G_OBJECT_CLASS (st_border_image_parent_class)->finalize (object);
} }
@ -67,18 +67,18 @@ st_border_image_init (StBorderImage *image)
} }
StBorderImage * StBorderImage *
st_border_image_new (const char *filename, st_border_image_new (GFile *file,
int border_top, int border_top,
int border_right, int border_right,
int border_bottom, int border_bottom,
int border_left, int border_left,
int scale_factor) int scale_factor)
{ {
StBorderImage *image; StBorderImage *image;
image = g_object_new (ST_TYPE_BORDER_IMAGE, NULL); image = g_object_new (ST_TYPE_BORDER_IMAGE, NULL);
image->filename = g_strdup (filename); image->file = g_object_ref (file);
image->border_top = border_top; image->border_top = border_top;
image->border_right = border_right; image->border_right = border_right;
image->border_bottom = border_bottom; image->border_bottom = border_bottom;
@ -88,12 +88,18 @@ st_border_image_new (const char *filename,
return image; return image;
} }
const char * /**
st_border_image_get_filename (StBorderImage *image) * st_border_image_get_file:
* @image: a #StBorder_Image
*
* Returns: (transfer none): the #GFile for the #StBorder_Image
*/
GFile *
st_border_image_get_file (StBorderImage *image)
{ {
g_return_val_if_fail (ST_IS_BORDER_IMAGE (image), NULL); g_return_val_if_fail (ST_IS_BORDER_IMAGE (image), NULL);
return image->filename; return image->file;
} }
void void
@ -135,5 +141,5 @@ st_border_image_equal (StBorderImage *image,
image->border_right == other->border_right && image->border_right == other->border_right &&
image->border_bottom == other->border_bottom && image->border_bottom == other->border_bottom &&
image->border_left == other->border_left && image->border_left == other->border_left &&
strcmp (image->filename, other->filename) == 0); g_file_equal (image->file, other->file));
} }

View File

@ -22,6 +22,7 @@
#define __ST_BORDER_IMAGE_H__ #define __ST_BORDER_IMAGE_H__
#include <glib-object.h> #include <glib-object.h>
#include <gio/gio.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -39,14 +40,14 @@ typedef struct _StBorderImageClass StBorderImageClass;
GType st_border_image_get_type (void) G_GNUC_CONST; GType st_border_image_get_type (void) G_GNUC_CONST;
StBorderImage *st_border_image_new (const char *filename, StBorderImage *st_border_image_new (GFile *file,
int border_top, int border_top,
int border_right, int border_right,
int border_bottom, int border_bottom,
int border_left, int border_left,
int scale_factor); int scale_factor);
const char *st_border_image_get_filename (StBorderImage *image); GFile *st_border_image_get_file (StBorderImage *image);
void st_border_image_get_borders (StBorderImage *image, void st_border_image_get_borders (StBorderImage *image,
int *border_top, int *border_top,
int *border_right, int *border_right,

View File

@ -28,8 +28,8 @@
#include <glib.h> #include <glib.h>
#define CACHE_PREFIX_ICON "icon:" #define CACHE_PREFIX_ICON "icon:"
#define CACHE_PREFIX_URI "uri:" #define CACHE_PREFIX_FILE "file:"
#define CACHE_PREFIX_URI_FOR_CAIRO "uri-for-cairo:" #define CACHE_PREFIX_FILE_FOR_CAIRO "file-for-cairo:"
struct _StTextureCachePrivate struct _StTextureCachePrivate
{ {
@ -101,7 +101,7 @@ st_texture_cache_class_init (StTextureCacheClass *klass)
G_SIGNAL_RUN_LAST, G_SIGNAL_RUN_LAST,
0, /* no default handler slot */ 0, /* no default handler slot */
NULL, NULL, NULL, NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_STRING); G_TYPE_NONE, 1, G_TYPE_FILE);
} }
/* Evicts all cached textures for named icons */ /* Evicts all cached textures for named icons */
@ -147,7 +147,7 @@ st_texture_cache_init (StTextureCache *self)
g_free, cogl_object_unref); g_free, cogl_object_unref);
self->priv->outstanding_requests = g_hash_table_new_full (g_str_hash, g_str_equal, self->priv->outstanding_requests = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, NULL); g_free, NULL);
self->priv->file_monitors = g_hash_table_new_full (g_str_hash, g_str_equal, self->priv->file_monitors = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal,
g_object_unref, g_object_unref); g_object_unref, g_object_unref);
} }
@ -268,7 +268,7 @@ typedef struct {
GtkIconInfo *icon_info; GtkIconInfo *icon_info;
StIconColors *colors; StIconColors *colors;
char *uri; GFile *file;
} AsyncTextureLoadData; } AsyncTextureLoadData;
static void static void
@ -282,8 +282,8 @@ texture_load_data_free (gpointer p)
if (data->colors) if (data->colors)
st_icon_colors_unref (data->colors); st_icon_colors_unref (data->colors);
} }
else if (data->uri) else if (data->file)
g_free (data->uri); g_object_unref (data->file);
if (data->key) if (data->key)
g_free (data->key); g_free (data->key);
@ -406,18 +406,16 @@ out:
} }
static GdkPixbuf * static GdkPixbuf *
impl_load_pixbuf_file (const char *uri, impl_load_pixbuf_file (GFile *file,
int available_width, int available_width,
int available_height, int available_height,
int scale, int scale,
GError **error) GError **error)
{ {
GdkPixbuf *pixbuf = NULL; GdkPixbuf *pixbuf = NULL;
GFile *file;
char *contents = NULL; char *contents = NULL;
gsize size; gsize size;
file = g_file_new_for_uri (uri);
if (g_file_load_contents (file, NULL, &contents, &size, NULL, error)) if (g_file_load_contents (file, NULL, &contents, &size, NULL, error))
{ {
pixbuf = impl_load_pixbuf_data ((const guchar *) contents, size, pixbuf = impl_load_pixbuf_data ((const guchar *) contents, size,
@ -426,7 +424,6 @@ impl_load_pixbuf_file (const char *uri,
error); error);
} }
g_object_unref (file);
g_free (contents); g_free (contents);
return pixbuf; return pixbuf;
@ -443,9 +440,9 @@ load_pixbuf_thread (GSimpleAsyncResult *result,
data = g_async_result_get_user_data (G_ASYNC_RESULT (result)); data = g_async_result_get_user_data (G_ASYNC_RESULT (result));
g_assert (data != NULL); g_assert (data != NULL);
g_assert (data->uri != NULL); g_assert (data->file != NULL);
pixbuf = impl_load_pixbuf_file (data->uri, data->width, data->height, data->scale, &error); pixbuf = impl_load_pixbuf_file (data->file, data->width, data->height, data->scale, &error);
if (error != NULL) if (error != NULL)
{ {
@ -583,7 +580,7 @@ static void
load_texture_async (StTextureCache *cache, load_texture_async (StTextureCache *cache,
AsyncTextureLoadData *data) AsyncTextureLoadData *data)
{ {
if (data->uri) if (data->file)
{ {
GSimpleAsyncResult *result; GSimpleAsyncResult *result;
result = g_simple_async_result_new (G_OBJECT (cache), on_pixbuf_loaded, data, load_texture_async); result = g_simple_async_result_new (G_OBJECT (cache), on_pixbuf_loaded, data, load_texture_async);
@ -950,46 +947,43 @@ file_changed_cb (GFileMonitor *monitor,
gpointer user_data) gpointer user_data)
{ {
StTextureCache *cache = user_data; StTextureCache *cache = user_data;
char *uri, *key; char *key;
guint file_hash;
if (event_type != G_FILE_MONITOR_EVENT_CHANGED) if (event_type != G_FILE_MONITOR_EVENT_CHANGED)
return; return;
uri = g_file_get_uri (file); file_hash = g_file_hash (file);
key = g_strconcat (CACHE_PREFIX_URI, uri, NULL); key = g_strdup_printf (CACHE_PREFIX_FILE "%u", file_hash);
g_hash_table_remove (cache->priv->keyed_cache, key); g_hash_table_remove (cache->priv->keyed_cache, key);
g_free (key); g_free (key);
key = g_strconcat (CACHE_PREFIX_URI_FOR_CAIRO, uri, NULL); key = g_strdup_printf (CACHE_PREFIX_FILE_FOR_CAIRO "%u", file_hash);
g_hash_table_remove (cache->priv->keyed_cache, key); g_hash_table_remove (cache->priv->keyed_cache, key);
g_free (key); g_free (key);
g_signal_emit (cache, signals[TEXTURE_FILE_CHANGED], 0, uri); g_signal_emit (cache, signals[TEXTURE_FILE_CHANGED], 0, file);
g_free (uri);
} }
static void static void
ensure_monitor_for_uri (StTextureCache *cache, ensure_monitor_for_file (StTextureCache *cache,
const gchar *uri) GFile *file)
{ {
StTextureCachePrivate *priv = cache->priv; StTextureCachePrivate *priv = cache->priv;
GFile *file = g_file_new_for_uri (uri);
if (g_hash_table_lookup (priv->file_monitors, uri) == NULL) if (g_hash_table_lookup (priv->file_monitors, file) == NULL)
{ {
GFileMonitor *monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, GFileMonitor *monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE,
NULL, NULL); NULL, NULL);
g_signal_connect (monitor, "changed", g_signal_connect (monitor, "changed",
G_CALLBACK (file_changed_cb), cache); G_CALLBACK (file_changed_cb), cache);
g_hash_table_insert (priv->file_monitors, g_strdup (uri), monitor); g_hash_table_insert (priv->file_monitors, g_object_ref (file), monitor);
} }
g_object_unref (file);
} }
typedef struct { typedef struct {
gchar *path; GFile *gfile;
gint grid_width, grid_height; gint grid_width, grid_height;
gint scale_factor; gint scale_factor;
ClutterActor *actor; ClutterActor *actor;
@ -1001,7 +995,7 @@ static void
on_data_destroy (gpointer data) on_data_destroy (gpointer data)
{ {
AsyncImageData *d = (AsyncImageData *)data; AsyncImageData *d = (AsyncImageData *)data;
g_free (d->path); g_object_unref (d->gfile);
g_object_unref (d->actor); g_object_unref (d->actor);
g_free (d); g_free (d);
} }
@ -1074,7 +1068,7 @@ load_sliced_image (GSimpleAsyncResult *result,
loader = gdk_pixbuf_loader_new (); loader = gdk_pixbuf_loader_new ();
g_signal_connect (loader, "size-prepared", G_CALLBACK (on_loader_size_prepared), data); g_signal_connect (loader, "size-prepared", G_CALLBACK (on_loader_size_prepared), data);
if (!g_file_get_contents (data->path, &buffer, &length, NULL)) if (!g_file_load_contents (data->gfile, NULL, &buffer, &length, NULL, NULL))
goto out; goto out;
if (!gdk_pixbuf_loader_write (loader, (const guchar *) buffer, length, NULL)) if (!gdk_pixbuf_loader_write (loader, (const guchar *) buffer, length, NULL))
@ -1109,7 +1103,7 @@ load_sliced_image (GSimpleAsyncResult *result,
/** /**
* st_texture_cache_load_sliced_image: * st_texture_cache_load_sliced_image:
* @cache: A #StTextureCache * @cache: A #StTextureCache
* @path: Path to a filename * @file: A #GFile
* @grid_width: Width in pixels * @grid_width: Width in pixels
* @grid_height: Height in pixels * @grid_height: Height in pixels
* @scale: Scale factor of the display * @scale: Scale factor of the display
@ -1125,7 +1119,7 @@ load_sliced_image (GSimpleAsyncResult *result,
*/ */
ClutterActor * ClutterActor *
st_texture_cache_load_sliced_image (StTextureCache *cache, st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path, GFile *file,
gint grid_width, gint grid_width,
gint grid_height, gint grid_height,
gint scale, gint scale,
@ -1140,7 +1134,7 @@ st_texture_cache_load_sliced_image (StTextureCache *cache,
data->grid_width = grid_width; data->grid_width = grid_width;
data->grid_height = grid_height; data->grid_height = grid_height;
data->scale_factor = scale; data->scale_factor = scale;
data->path = g_strdup (path); data->gfile = g_object_ref (file);
data->actor = actor; data->actor = actor;
data->load_callback = load_callback; data->load_callback = load_callback;
data->load_callback_data = user_data; data->load_callback_data = user_data;
@ -1157,9 +1151,9 @@ st_texture_cache_load_sliced_image (StTextureCache *cache,
} }
/** /**
* st_texture_cache_load_uri_async: * st_texture_cache_load_file_async:
* @cache: The texture cache instance * @cache: The texture cache instance
* @uri: uri of the image file from which to create a pixbuf * @file: a #GFile 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
* @scale: scale factor of the display * @scale: scale factor of the display
@ -1171,18 +1165,18 @@ st_texture_cache_load_sliced_image (StTextureCache *cache,
* Return value: (transfer none): A new #ClutterActor with no image loaded initially. * Return value: (transfer none): A new #ClutterActor with no image loaded initially.
*/ */
ClutterActor * ClutterActor *
st_texture_cache_load_uri_async (StTextureCache *cache, st_texture_cache_load_file_async (StTextureCache *cache,
const gchar *uri, GFile *file,
int available_width, int available_width,
int available_height, int available_height,
int scale) int scale)
{ {
ClutterActor *texture; ClutterActor *texture;
AsyncTextureLoadData *request; AsyncTextureLoadData *request;
StTextureCachePolicy policy; StTextureCachePolicy policy;
gchar *key; gchar *key;
key = g_strconcat (CACHE_PREFIX_URI, uri, NULL); key = g_strdup_printf (CACHE_PREFIX_FILE "%u", g_file_hash (file));
policy = ST_TEXTURE_CACHE_POLICY_NONE; /* XXX */ policy = ST_TEXTURE_CACHE_POLICY_NONE; /* XXX */
@ -1200,7 +1194,7 @@ st_texture_cache_load_uri_async (StTextureCache *cache,
request->cache = cache; request->cache = cache;
/* Transfer ownership of key */ /* Transfer ownership of key */
request->key = key; request->key = key;
request->uri = g_strdup (uri); request->file = g_object_ref (file);
request->policy = policy; request->policy = policy;
request->width = available_width; request->width = available_width;
request->height = available_height; request->height = available_height;
@ -1209,31 +1203,31 @@ st_texture_cache_load_uri_async (StTextureCache *cache,
load_texture_async (cache, request); load_texture_async (cache, request);
} }
ensure_monitor_for_uri (cache, uri); ensure_monitor_for_file (cache, file);
return CLUTTER_ACTOR (texture); return CLUTTER_ACTOR (texture);
} }
static CoglTexture * static CoglTexture *
st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache, st_texture_cache_load_file_sync_to_cogl_texture (StTextureCache *cache,
StTextureCachePolicy policy, StTextureCachePolicy policy,
const gchar *uri, GFile *file,
int available_width, int available_width,
int available_height, int available_height,
int scale, int scale,
GError **error) GError **error)
{ {
CoglTexture *texdata; CoglTexture *texdata;
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
char *key; char *key;
key = g_strconcat (CACHE_PREFIX_URI, uri, NULL); key = g_strdup_printf (CACHE_PREFIX_FILE "%u", g_file_hash (file));
texdata = g_hash_table_lookup (cache->priv->keyed_cache, key); texdata = g_hash_table_lookup (cache->priv->keyed_cache, key);
if (texdata == NULL) if (texdata == NULL)
{ {
pixbuf = impl_load_pixbuf_file (uri, available_width, available_height, scale, error); pixbuf = impl_load_pixbuf_file (file, available_width, available_height, scale, error);
if (!pixbuf) if (!pixbuf)
goto out; goto out;
@ -1249,7 +1243,7 @@ st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache,
else else
cogl_object_ref (texdata); cogl_object_ref (texdata);
ensure_monitor_for_uri (cache, uri); ensure_monitor_for_file (cache, file);
out: out:
g_free (key); g_free (key);
@ -1257,25 +1251,25 @@ out:
} }
static cairo_surface_t * static cairo_surface_t *
st_texture_cache_load_uri_sync_to_cairo_surface (StTextureCache *cache, st_texture_cache_load_file_sync_to_cairo_surface (StTextureCache *cache,
StTextureCachePolicy policy, StTextureCachePolicy policy,
const gchar *uri, GFile *file,
int available_width, int available_width,
int available_height, int available_height,
int scale, int scale,
GError **error) GError **error)
{ {
cairo_surface_t *surface; cairo_surface_t *surface;
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
char *key; char *key;
key = g_strconcat (CACHE_PREFIX_URI_FOR_CAIRO, uri, NULL); key = g_strdup_printf (CACHE_PREFIX_FILE_FOR_CAIRO "%u", g_file_hash (file));
surface = g_hash_table_lookup (cache->priv->keyed_cache, key); surface = g_hash_table_lookup (cache->priv->keyed_cache, key);
if (surface == NULL) if (surface == NULL)
{ {
pixbuf = impl_load_pixbuf_file (uri, available_width, available_height, scale, error); pixbuf = impl_load_pixbuf_file (file, available_width, available_height, scale, error);
if (!pixbuf) if (!pixbuf)
goto out; goto out;
@ -1291,7 +1285,7 @@ st_texture_cache_load_uri_sync_to_cairo_surface (StTextureCache *cache,
else else
cairo_surface_reference (surface); cairo_surface_reference (surface);
ensure_monitor_for_uri (cache, uri); ensure_monitor_for_file (cache, file);
out: out:
g_free (key); g_free (key);
@ -1301,7 +1295,7 @@ out:
/** /**
* st_texture_cache_load_file_to_cogl_texture: (skip) * st_texture_cache_load_file_to_cogl_texture: (skip)
* @cache: A #StTextureCache * @cache: A #StTextureCache
* @file_path: Path to a file in supported image format * @file: A #GFile in supported image format
* @scale: Scale factor of the display * @scale: Scale factor of the display
* *
* This function synchronously loads the given file path * This function synchronously loads the given file path
@ -1312,35 +1306,30 @@ out:
*/ */
CoglTexture * CoglTexture *
st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache, st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
const gchar *file_path, GFile *file,
gint scale) gint scale)
{ {
CoglTexture *texture; CoglTexture *texture;
GFile *file;
char *uri;
GError *error = NULL; GError *error = NULL;
file = g_file_new_for_path (file_path); texture = st_texture_cache_load_file_sync_to_cogl_texture (cache, ST_TEXTURE_CACHE_POLICY_FOREVER,
uri = g_file_get_uri (file); file, -1, -1, scale, &error);
texture = st_texture_cache_load_uri_sync_to_cogl_texture (cache, ST_TEXTURE_CACHE_POLICY_FOREVER,
uri, -1, -1, scale, &error);
g_object_unref (file);
g_free (uri);
if (texture == NULL) if (texture == NULL)
{ {
g_warning ("Failed to load %s: %s", file_path, error->message); char *uri = g_file_get_uri (file);
g_warning ("Failed to load %s: %s", uri, error->message);
g_clear_error (&error); g_clear_error (&error);
return NULL; g_free (uri);
} }
return texture; return texture;
} }
/** /**
* st_texture_cache_load_file_to_cairo_surface: * st_texture_cache_load_file_to_cairo_surface:
* @cache: A #StTextureCache * @cache: A #StTextureCache
* @file_path: Path to a file in supported image format * @file: A #GFile in supported image format
* @scale: Scale factor of the display * @scale: Scale factor of the display
* *
* This function synchronously loads the given file path * This function synchronously loads the given file path
@ -1351,28 +1340,23 @@ st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
*/ */
cairo_surface_t * cairo_surface_t *
st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache, st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
const gchar *file_path, GFile *file,
gint scale) gint scale)
{ {
cairo_surface_t *surface; cairo_surface_t *surface;
GFile *file;
char *uri;
GError *error = NULL; GError *error = NULL;
file = g_file_new_for_path (file_path); surface = st_texture_cache_load_file_sync_to_cairo_surface (cache, ST_TEXTURE_CACHE_POLICY_FOREVER,
uri = g_file_get_uri (file); file, -1, -1, scale, &error);
surface = st_texture_cache_load_uri_sync_to_cairo_surface (cache, ST_TEXTURE_CACHE_POLICY_FOREVER,
uri, -1, -1, scale, &error);
g_object_unref (file);
g_free (uri);
if (surface == NULL) if (surface == NULL)
{ {
g_warning ("Failed to load %s: %s", file_path, error->message); char *uri = g_file_get_uri (file);
g_warning ("Failed to load %s: %s", uri, error->message);
g_clear_error (&error); g_clear_error (&error);
return NULL; g_free (uri);
} }
return surface; return surface;
} }

View File

@ -70,7 +70,7 @@ StTextureCache* st_texture_cache_get_default (void);
ClutterActor * ClutterActor *
st_texture_cache_load_sliced_image (StTextureCache *cache, st_texture_cache_load_sliced_image (StTextureCache *cache,
const gchar *path, GFile *file,
gint grid_width, gint grid_width,
gint grid_height, gint grid_height,
gint scale, gint scale,
@ -87,18 +87,18 @@ ClutterActor *st_texture_cache_load_gicon (StTextureCache *cache,
gint size, gint size,
gint scale); gint scale);
ClutterActor *st_texture_cache_load_uri_async (StTextureCache *cache, ClutterActor *st_texture_cache_load_file_async (StTextureCache *cache,
const gchar *uri, GFile *file,
int available_width, int available_width,
int available_height, int available_height,
int scale); int scale);
CoglTexture *st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache, CoglTexture *st_texture_cache_load_file_to_cogl_texture (StTextureCache *cache,
const gchar *file_path, GFile *file,
gint scale); gint scale);
cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache, cairo_surface_t *st_texture_cache_load_file_to_cairo_surface (StTextureCache *cache,
const gchar *file_path, GFile *file,
gint scale); gint scale);
/** /**

View File

@ -600,7 +600,7 @@ create_cairo_pattern_of_background_image (StThemeNode *node,
cairo_pattern_t *pattern; cairo_pattern_t *pattern;
cairo_content_t content; cairo_content_t content;
cairo_matrix_t matrix; cairo_matrix_t matrix;
const char *file; GFile *file;
StTextureCache *texture_cache; StTextureCache *texture_cache;
@ -1037,7 +1037,7 @@ st_theme_node_prerender_background (StThemeNode *node,
} }
else else
{ {
const char *background_image; GFile *background_image;
background_image = st_theme_node_get_background_image (node); background_image = st_theme_node_get_background_image (node);
@ -1303,14 +1303,14 @@ st_theme_node_load_border_image (StThemeNode *node)
if (border_image == NULL) if (border_image == NULL)
goto out; goto out;
const char *filename; GFile *file;
filename = st_border_image_get_filename (border_image); file = st_border_image_get_file (border_image);
int scale_factor; int scale_factor;
g_object_get (node->context, "scale-factor", &scale_factor, NULL); g_object_get (node->context, "scale-factor", &scale_factor, NULL);
node->border_slices_texture = st_texture_cache_load_file_to_cogl_texture (st_texture_cache_get_default (), node->border_slices_texture = st_texture_cache_load_file_to_cogl_texture (st_texture_cache_get_default (),
filename, scale_factor); file, scale_factor);
if (node->border_slices_texture == COGL_INVALID_HANDLE) if (node->border_slices_texture == COGL_INVALID_HANDLE)
goto out; goto out;
@ -1348,7 +1348,7 @@ st_theme_node_load_background_image (StThemeNode *node)
{ {
if (node->background_texture == COGL_INVALID_HANDLE) if (node->background_texture == COGL_INVALID_HANDLE)
{ {
const char *background_image; GFile *background_image;
StShadow *background_image_shadow_spec; StShadow *background_image_shadow_spec;
background_image = st_theme_node_get_background_image (node); background_image = st_theme_node_get_background_image (node);

View File

@ -68,7 +68,7 @@ struct _StThemeNode {
int transition_duration; int transition_duration;
char *background_image; GFile *background_image;
StBorderImage *border_image; StBorderImage *border_image;
StShadow *box_shadow; StShadow *box_shadow;
StShadow *background_image_shadow; StShadow *background_image_shadow;

View File

@ -158,7 +158,10 @@ st_theme_node_finalize (GObject *object)
} }
if (node->background_image) if (node->background_image)
g_free (node->background_image); {
g_object_unref (node->background_image);
node->background_image = NULL;
}
if (node->background_texture != COGL_INVALID_HANDLE) if (node->background_texture != COGL_INVALID_HANDLE)
cogl_handle_unref (node->background_texture); cogl_handle_unref (node->background_texture);
@ -905,7 +908,7 @@ st_theme_node_get_double (StThemeNode *node,
* parent's parent, and so forth. Note that if the property has a * parent's parent, and so forth. Note that if the property has a
* value of 'inherit' it will be inherited even if %FALSE is passed * value of 'inherit' it will be inherited even if %FALSE is passed
* in for @inherit; this only affects the default behavior for inheritance. * in for @inherit; this only affects the default behavior for inheritance.
* @value: (out): location to store the newly allocated value that was * @file: (out) (transfer full): location to store the newly allocated value that was
* determined. If the property is not found, the value in this location * determined. If the property is not found, the value in this location
* will not be changed. * will not be changed.
* *
@ -920,7 +923,7 @@ gboolean
st_theme_node_lookup_url (StThemeNode *node, st_theme_node_lookup_url (StThemeNode *node,
const char *property_name, const char *property_name,
gboolean inherit, gboolean inherit,
char **value) GFile **file)
{ {
gboolean result = FALSE; gboolean result = FALSE;
int i; int i;
@ -935,7 +938,6 @@ st_theme_node_lookup_url (StThemeNode *node,
{ {
CRTerm *term = decl->value; CRTerm *term = decl->value;
CRStyleSheet *base_stylesheet; CRStyleSheet *base_stylesheet;
GFile *file;
if (term->type != TERM_URI && term->type != TERM_STRING) if (term->type != TERM_URI && term->type != TERM_STRING)
continue; continue;
@ -945,23 +947,21 @@ st_theme_node_lookup_url (StThemeNode *node,
else else
base_stylesheet = NULL; base_stylesheet = NULL;
file = _st_theme_resolve_url (node->theme, *file = _st_theme_resolve_url (node->theme,
base_stylesheet, base_stylesheet,
decl->value->content.str->stryng->str); decl->value->content.str->stryng->str);
*value = g_file_get_path (file);
g_object_unref (file);
result = TRUE; result = TRUE;
break; break;
} }
} }
if (!result && inherit && node->parent_node) if (!result && inherit && node->parent_node)
result = st_theme_node_lookup_url (node->parent_node, property_name, inherit, value); result = st_theme_node_lookup_url (node->parent_node, property_name, inherit, file);
return result; return result;
} }
/* /**
* st_theme_node_get_url: * st_theme_node_get_url:
* @node: a #StThemeNode * @node: a #StThemeNode
* @property_name: The name of the string property * @property_name: The name of the string property
@ -972,18 +972,18 @@ st_theme_node_lookup_url (StThemeNode *node,
* and lets you handle the case where the theme does not specify the * and lets you handle the case where the theme does not specify the
* indicated value. * indicated value.
* *
* Return value: the newly allocated value if found. * Returns: (transfer full): the newly allocated value if found.
* If @property_name is not found, a warning will be logged and %NULL * If @property_name is not found, a warning will be logged and %NULL
* will be returned. * will be returned.
*/ */
char * GFile *
st_theme_node_get_url (StThemeNode *node, st_theme_node_get_url (StThemeNode *node,
const char *property_name) const char *property_name)
{ {
char *value; GFile *file;
if (st_theme_node_lookup_url (node, property_name, FALSE, &value)) if (st_theme_node_lookup_url (node, property_name, FALSE, &file))
return value; return file;
else else
{ {
g_warning ("Did not find string property '%s'", property_name); g_warning ("Did not find string property '%s'", property_name);
@ -1926,8 +1926,7 @@ _st_theme_node_ensure_background (StThemeNode *node)
CRTerm *term; CRTerm *term;
/* background: property sets all terms to specified or default values */ /* background: property sets all terms to specified or default values */
node->background_color = TRANSPARENT_COLOR; node->background_color = TRANSPARENT_COLOR;
g_free (node->background_image); g_clear_object (&node->background_image);
node->background_image = NULL;
node->background_position_set = FALSE; node->background_position_set = FALSE;
node->background_size = ST_BACKGROUND_SIZE_AUTO; node->background_size = ST_BACKGROUND_SIZE_AUTO;
@ -1943,7 +1942,7 @@ _st_theme_node_ensure_background (StThemeNode *node)
if (node->parent_node) if (node->parent_node)
{ {
st_theme_node_get_background_color (node->parent_node, &node->background_color); st_theme_node_get_background_color (node->parent_node, &node->background_color);
node->background_image = g_strdup (st_theme_node_get_background_image (node->parent_node)); node->background_image = g_object_ref (st_theme_node_get_background_image (node->parent_node));
} }
} }
else if (term_is_none (term)) else if (term_is_none (term))
@ -1964,8 +1963,7 @@ _st_theme_node_ensure_background (StThemeNode *node)
base_stylesheet, base_stylesheet,
term->content.str->stryng->str); term->content.str->stryng->str);
node->background_image = g_file_get_path (file); node->background_image = file;
g_object_unref (file);
} }
} }
} }
@ -2062,30 +2060,25 @@ _st_theme_node_ensure_background (StThemeNode *node)
if (decl->value->type == TERM_URI) if (decl->value->type == TERM_URI)
{ {
CRStyleSheet *base_stylesheet; CRStyleSheet *base_stylesheet;
GFile *file;
if (decl->parent_statement != NULL) if (decl->parent_statement != NULL)
base_stylesheet = decl->parent_statement->parent_sheet; base_stylesheet = decl->parent_statement->parent_sheet;
else else
base_stylesheet = NULL; base_stylesheet = NULL;
g_free (node->background_image); g_clear_object (&node->background_image);
file = _st_theme_resolve_url (node->theme, node->background_image = _st_theme_resolve_url (node->theme,
base_stylesheet, base_stylesheet,
decl->value->content.str->stryng->str); decl->value->content.str->stryng->str);
node->background_image = g_file_get_path (file);
g_object_unref (file);
} }
else if (term_is_inherit (decl->value)) else if (term_is_inherit (decl->value))
{ {
g_free (node->background_image); g_clear_object (&node->background_image);
node->background_image = g_strdup (st_theme_node_get_background_image (node->parent_node)); node->background_image = g_object_ref (st_theme_node_get_background_image (node->parent_node));
} }
else if (term_is_none (decl->value)) else if (term_is_none (decl->value))
{ {
g_free (node->background_image); g_clear_object (&node->background_image);
node->background_image = NULL;
} }
} }
else if (strcmp (property_name, "-gradient-direction") == 0) else if (strcmp (property_name, "-gradient-direction") == 0)
@ -2142,7 +2135,13 @@ st_theme_node_get_background_color (StThemeNode *node,
*color = node->background_color; *color = node->background_color;
} }
const char * /**
* st_theme_node_get_background_image:
* @node: a #StThemeNode
*
* Returns: (transfer none): @node's background image.
*/
GFile *
st_theme_node_get_background_image (StThemeNode *node) st_theme_node_get_background_image (StThemeNode *node)
{ {
g_return_val_if_fail (ST_IS_THEME_NODE (node), NULL); g_return_val_if_fail (ST_IS_THEME_NODE (node), NULL);
@ -2894,7 +2893,6 @@ st_theme_node_get_border_image (StThemeNode *node)
int border_left; int border_left;
GFile *file; GFile *file;
char *filename;
/* Support border-image: none; to suppress a previously specified border image */ /* Support border-image: none; to suppress a previously specified border image */
if (term_is_none (term)) if (term_is_none (term))
@ -2973,17 +2971,15 @@ st_theme_node_get_border_image (StThemeNode *node)
base_stylesheet = NULL; base_stylesheet = NULL;
file = _st_theme_resolve_url (node->theme, base_stylesheet, url); file = _st_theme_resolve_url (node->theme, base_stylesheet, url);
filename = g_file_get_path (file);
g_object_unref (file);
if (filename == NULL) if (file == NULL)
goto next_property; goto next_property;
node->border_image = st_border_image_new (filename, node->border_image = st_border_image_new (file,
border_top, border_right, border_bottom, border_left, border_top, border_right, border_bottom, border_left,
scale_factor); scale_factor);
g_free (filename); g_object_unref (file);
return node->border_image; return node->border_image;
} }
@ -3853,7 +3849,9 @@ st_theme_node_paint_equal (StThemeNode *node,
!clutter_color_equal (&node->background_gradient_end, &other->background_gradient_end)) !clutter_color_equal (&node->background_gradient_end, &other->background_gradient_end))
return FALSE; return FALSE;
if (g_strcmp0 (node->background_image, other->background_image) != 0) if ((node->background_image != NULL) &&
(other->background_image != NULL) &&
!g_file_equal (node->background_image, other->background_image))
return FALSE; return FALSE;
_st_theme_node_ensure_geometry (node); _st_theme_node_ensure_geometry (node);

View File

@ -162,7 +162,7 @@ gboolean st_theme_node_lookup_shadow (StThemeNode *node,
gboolean st_theme_node_lookup_url (StThemeNode *node, gboolean st_theme_node_lookup_url (StThemeNode *node,
const char *property_name, const char *property_name,
gboolean inherit, gboolean inherit,
char **value); GFile **file);
/* Easier-to-use variants of the above, for application-level use */ /* Easier-to-use variants of the above, for application-level use */
void st_theme_node_get_color (StThemeNode *node, void st_theme_node_get_color (StThemeNode *node,
@ -174,7 +174,7 @@ gdouble st_theme_node_get_length (StThemeNode *node,
const char *property_name); const char *property_name);
StShadow *st_theme_node_get_shadow (StThemeNode *node, StShadow *st_theme_node_get_shadow (StThemeNode *node,
const char *property_name); const char *property_name);
char *st_theme_node_get_url (StThemeNode *node, GFile *st_theme_node_get_url (StThemeNode *node,
const char *property_name); const char *property_name);
/* Specific getters for particular properties: cached /* Specific getters for particular properties: cached
@ -188,7 +188,7 @@ void st_theme_node_get_background_gradient (StThemeNode *node,
ClutterColor *start, ClutterColor *start,
ClutterColor *end); ClutterColor *end);
const char *st_theme_node_get_background_image (StThemeNode *node); GFile *st_theme_node_get_background_image (StThemeNode *node);
int st_theme_node_get_border_width (StThemeNode *node, int st_theme_node_get_border_width (StThemeNode *node,
StSide side); StSide side);

View File

@ -1008,8 +1008,8 @@ _st_theme_get_matched_properties (StTheme *theme,
return props; return props;
} }
/* Resolve an url from an url() reference in a stylesheet into an absolute /* Resolve an url from an url() reference in a stylesheet into a GFile,
* local filename, if possible. The resolution here is distinctly lame and * if possible. The resolution here is distinctly lame and
* will fail on many examples. * will fail on many examples.
*/ */
GFile * GFile *

View File

@ -277,26 +277,26 @@ current_paint_state (StWidget *widget)
static void static void
st_widget_texture_cache_changed (StTextureCache *cache, st_widget_texture_cache_changed (StTextureCache *cache,
const char *uri, GFile *file,
gpointer user_data) gpointer user_data)
{ {
StWidget *actor = ST_WIDGET (user_data); StWidget *actor = ST_WIDGET (user_data);
StThemeNode *node = actor->priv->theme_node; StThemeNode *node = actor->priv->theme_node;
char *path;
gboolean changed = FALSE; gboolean changed = FALSE;
GFile *theme_file;
if (node == NULL) if (node == NULL)
return; return;
path = g_filename_from_uri (uri, NULL, NULL); theme_file = st_theme_node_get_background_image (node);
if ((theme_file != NULL) && g_file_equal (theme_file, file))
if (g_strcmp0 (st_theme_node_get_background_image (node), path) == 0)
{ {
st_theme_node_invalidate_background_image (node); st_theme_node_invalidate_background_image (node);
changed = TRUE; changed = TRUE;
} }
if (g_strcmp0 (st_border_image_get_filename (st_theme_node_get_border_image (node)), path) == 0) theme_file = st_border_image_get_file (st_theme_node_get_border_image (node));
if ((theme_file != NULL) && g_file_equal (theme_file, file))
{ {
st_theme_node_invalidate_border_image (node); st_theme_node_invalidate_border_image (node);
changed = TRUE; changed = TRUE;
@ -317,8 +317,6 @@ st_widget_texture_cache_changed (StTextureCache *cache,
if (CLUTTER_ACTOR_IS_MAPPED (CLUTTER_ACTOR (actor))) if (CLUTTER_ACTOR_IS_MAPPED (CLUTTER_ACTOR (actor)))
clutter_actor_queue_redraw (CLUTTER_ACTOR (actor)); clutter_actor_queue_redraw (CLUTTER_ACTOR (actor));
} }
g_free (path);
} }
static void static void

View File

@ -173,17 +173,21 @@ assert_background_image (StThemeNode *node,
const char *node_description, const char *node_description,
const char *expected) const char *expected)
{ {
const char *value = st_theme_node_get_background_image (node); GFile *value = st_theme_node_get_background_image (node);
if (expected == NULL) GFile *expected_file;
expected = "(null)";
if (value == NULL)
value = "(null)";
if (strcmp (expected, value) != 0) if (expected != NULL && value != NULL)
{ {
g_print ("%s: %s.background-image: expected: %s, got: %s\n", expected_file = g_file_new_for_path (expected);
test, node_description, expected, value);
fail = TRUE; if (!g_file_equal (expected_file, value))
{
char *uri = g_file_get_uri (expected_file);
g_print ("%s: %s.background-image: expected: %s, got: %s\n",
test, node_description, expected, uri);
fail = TRUE;
g_free (uri);
}
} }
} }