st/texture-cache: Return a GIcon from bind_cairo_surface_property()
We still load the surface into an StImageContent, but instead of adding the content to an actor we hand out, return the content itself (as GIcon). That means we lose the ability to specify an icon size, but as we get the pixel data from a fixed-size surface anyway, that shouldn't matter much in practice. Not to mention that the function is only used for fallback X11 icons, which are already shit more often than not. https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1342
This commit is contained in:
parent
770231c2d7
commit
d7cb2eeebc
@ -180,66 +180,24 @@ window_backed_app_get_window (ShellApp *app)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClutterActor *
|
static GIcon *
|
||||||
window_backed_app_get_icon (ShellApp *app,
|
window_backed_app_get_icon (ShellApp *app)
|
||||||
int size)
|
|
||||||
{
|
{
|
||||||
MetaWindow *window = NULL;
|
MetaWindow *window = NULL;
|
||||||
StWidget *widget;
|
|
||||||
int scale, scaled_size;
|
|
||||||
ShellGlobal *global;
|
|
||||||
StThemeContext *context;
|
|
||||||
|
|
||||||
global = shell_global_get ();
|
|
||||||
context = st_theme_context_get_for_stage (shell_global_get_stage (global));
|
|
||||||
g_object_get (context, "scale-factor", &scale, NULL);
|
|
||||||
|
|
||||||
scaled_size = size * scale;
|
|
||||||
|
|
||||||
/* During a state transition from running to not-running for
|
/* During a state transition from running to not-running for
|
||||||
* window-backend apps, it's possible we get a request for the icon.
|
* window-backend apps, it's possible we get a request for the icon.
|
||||||
* Avoid asserting here and just return an empty image.
|
* Avoid asserting here and just return a fallback icon
|
||||||
*/
|
*/
|
||||||
if (app->running_state != NULL)
|
if (app->running_state != NULL)
|
||||||
window = window_backed_app_get_window (app);
|
window = window_backed_app_get_window (app);
|
||||||
|
|
||||||
if (window == NULL)
|
if (window &&
|
||||||
{
|
meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_X11)
|
||||||
ClutterActor *actor;
|
return st_texture_cache_bind_cairo_surface_property (st_texture_cache_get_default (),
|
||||||
|
|
||||||
actor = clutter_actor_new ();
|
|
||||||
g_object_set (actor,
|
|
||||||
"opacity", 0,
|
|
||||||
"width", (float) scaled_size,
|
|
||||||
"height", (float) scaled_size,
|
|
||||||
NULL);
|
|
||||||
return actor;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meta_window_get_client_type (window) == META_WINDOW_CLIENT_TYPE_X11)
|
|
||||||
{
|
|
||||||
StWidget *texture_actor;
|
|
||||||
|
|
||||||
texture_actor =
|
|
||||||
st_texture_cache_bind_cairo_surface_property (st_texture_cache_get_default (),
|
|
||||||
G_OBJECT (window),
|
G_OBJECT (window),
|
||||||
"icon",
|
"icon");
|
||||||
scaled_size);
|
return g_themed_icon_new ("application-x-executable");
|
||||||
|
|
||||||
widget = g_object_new (ST_TYPE_BIN,
|
|
||||||
"child", texture_actor,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
widget = g_object_new (ST_TYPE_ICON,
|
|
||||||
"icon-size", size,
|
|
||||||
"icon-name", "application-x-executable",
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
st_widget_add_style_class_name (widget, "fallback-app-icon");
|
|
||||||
|
|
||||||
return CLUTTER_ACTOR (widget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -254,17 +212,24 @@ ClutterActor *
|
|||||||
shell_app_create_icon_texture (ShellApp *app,
|
shell_app_create_icon_texture (ShellApp *app,
|
||||||
int size)
|
int size)
|
||||||
{
|
{
|
||||||
GIcon *icon;
|
g_autoptr (GIcon) icon = NULL;
|
||||||
ClutterActor *ret;
|
ClutterActor *ret;
|
||||||
|
|
||||||
if (app->info == NULL)
|
|
||||||
return window_backed_app_get_icon (app, size);
|
|
||||||
|
|
||||||
ret = st_icon_new ();
|
ret = st_icon_new ();
|
||||||
st_icon_set_icon_size (ST_ICON (ret), size);
|
st_icon_set_icon_size (ST_ICON (ret), size);
|
||||||
st_icon_set_fallback_icon_name (ST_ICON (ret), "application-x-executable");
|
st_icon_set_fallback_icon_name (ST_ICON (ret), "application-x-executable");
|
||||||
|
|
||||||
|
if (app->info == NULL)
|
||||||
|
{
|
||||||
|
icon = window_backed_app_get_icon (app);
|
||||||
|
st_widget_add_style_class_name (ST_WIDGET (ret), "fallback-app-icon");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
icon = g_app_info_get_icon (G_APP_INFO (app->info));
|
icon = g_app_info_get_icon (G_APP_INFO (app->info));
|
||||||
|
g_object_ref (icon);
|
||||||
|
}
|
||||||
|
|
||||||
st_icon_set_gicon (ST_ICON (ret), icon);
|
st_icon_set_gicon (ST_ICON (ret), icon);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -722,8 +722,7 @@ load_texture_async (StTextureCache *cache,
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
StTextureCache *cache;
|
StTextureCache *cache;
|
||||||
ClutterActor *actor;
|
ClutterContent *image;
|
||||||
gint size;
|
|
||||||
GObject *source;
|
GObject *source;
|
||||||
gulong notify_signal_id;
|
gulong notify_signal_id;
|
||||||
gboolean weakref_active;
|
gboolean weakref_active;
|
||||||
@ -742,37 +741,33 @@ st_texture_cache_reset_texture (StTextureCachePropertyBind *bind,
|
|||||||
(cairo_image_surface_get_format (surface) == CAIRO_FORMAT_ARGB32 ||
|
(cairo_image_surface_get_format (surface) == CAIRO_FORMAT_ARGB32 ||
|
||||||
cairo_image_surface_get_format (surface) == CAIRO_FORMAT_RGB24))
|
cairo_image_surface_get_format (surface) == CAIRO_FORMAT_RGB24))
|
||||||
{
|
{
|
||||||
g_autoptr(ClutterContent) image = NULL;
|
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
int size = bind->size;
|
int width, height, size;
|
||||||
|
|
||||||
if (size < 0)
|
width = cairo_image_surface_get_width (surface);
|
||||||
clutter_actor_get_preferred_width (bind->actor, -1, NULL, (float *)&size);
|
height = cairo_image_surface_get_width (surface);
|
||||||
|
size = MAX(width, height);
|
||||||
|
|
||||||
image = clutter_actor_get_content (bind->actor);
|
if (!bind->image)
|
||||||
if (!image || !CLUTTER_IS_IMAGE (image))
|
bind->image = st_image_content_new_with_preferred_size (size, size);
|
||||||
image = st_image_content_new_with_preferred_size (size, size);
|
|
||||||
else
|
|
||||||
g_object_ref (image);
|
|
||||||
|
|
||||||
clutter_image_set_data (CLUTTER_IMAGE (image),
|
clutter_image_set_data (CLUTTER_IMAGE (bind->image),
|
||||||
cairo_image_surface_get_data (surface),
|
cairo_image_surface_get_data (surface),
|
||||||
cairo_image_surface_get_format (surface) == CAIRO_FORMAT_ARGB32 ?
|
cairo_image_surface_get_format (surface) == CAIRO_FORMAT_ARGB32 ?
|
||||||
COGL_PIXEL_FORMAT_BGRA_8888 : COGL_PIXEL_FORMAT_BGR_888,
|
COGL_PIXEL_FORMAT_BGRA_8888 : COGL_PIXEL_FORMAT_BGR_888,
|
||||||
cairo_image_surface_get_width (surface),
|
width,
|
||||||
cairo_image_surface_get_height (surface),
|
height,
|
||||||
cairo_image_surface_get_stride (surface),
|
cairo_image_surface_get_stride (surface),
|
||||||
&error);
|
&error);
|
||||||
|
|
||||||
if (image)
|
if (error)
|
||||||
clutter_actor_set_content (bind->actor, image);
|
|
||||||
else if (error)
|
|
||||||
g_warning ("Failed to allocate texture: %s", error->message);
|
g_warning ("Failed to allocate texture: %s", error->message);
|
||||||
|
|
||||||
clutter_actor_set_opacity (bind->actor, 255);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
clutter_actor_set_opacity (bind->actor, 0);
|
bind->image = g_object_new (ST_TYPE_IMAGE_CONTENT,
|
||||||
|
"preferred-width", 0, /* tough luck */
|
||||||
|
"preferred-height", 0,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -798,57 +793,48 @@ st_texture_cache_free_bind (gpointer data)
|
|||||||
{
|
{
|
||||||
StTextureCachePropertyBind *bind = data;
|
StTextureCachePropertyBind *bind = data;
|
||||||
if (bind->weakref_active)
|
if (bind->weakref_active)
|
||||||
g_object_weak_unref (G_OBJECT (bind->actor), st_texture_cache_bind_weak_notify, bind);
|
g_object_weak_unref (G_OBJECT (bind->image), st_texture_cache_bind_weak_notify, bind);
|
||||||
g_slice_free (StTextureCachePropertyBind, bind);
|
g_slice_free (StTextureCachePropertyBind, bind);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* st_texture_cache_bind_cairo_surface_property:
|
* st_texture_cache_bind_cairo_surface_property:
|
||||||
* @cache:
|
* @cache:
|
||||||
* @object: A #GObject with a property @property_name of type #GdkPixbuf
|
* @object: A #GObject with a property @property_name of type #cairo_surface_t
|
||||||
* @property_name: Name of a property
|
* @property_name: Name of a property
|
||||||
*
|
*
|
||||||
* Create a #ClutterActor which tracks the #cairo_surface_t value of a GObject property
|
* Create a #GIcon which tracks the #cairo_surface_t value of a GObject property
|
||||||
* named by @property_name. Unlike other methods in StTextureCache, the underlying
|
* named by @property_name. Unlike other methods in StTextureCache, the underlying
|
||||||
* #CoglTexture is not shared by default with other invocations to this method.
|
* #CoglTexture is not shared by default with other invocations to this method.
|
||||||
*
|
*
|
||||||
* If the source object is destroyed, the texture will continue to show the last
|
* If the source object is destroyed, the texture will continue to show the last
|
||||||
* value of the property.
|
* value of the property.
|
||||||
*
|
*
|
||||||
* Return value: (transfer none): A new #StWidget
|
* Return value: (transfer none): A new #GIcon
|
||||||
*/
|
*/
|
||||||
StWidget *
|
GIcon *
|
||||||
st_texture_cache_bind_cairo_surface_property (StTextureCache *cache,
|
st_texture_cache_bind_cairo_surface_property (StTextureCache *cache,
|
||||||
GObject *object,
|
GObject *object,
|
||||||
const char *property_name,
|
const char *property_name)
|
||||||
gint size)
|
|
||||||
{
|
{
|
||||||
StWidget *widget;
|
|
||||||
gchar *notify_key;
|
gchar *notify_key;
|
||||||
StTextureCachePropertyBind *bind;
|
StTextureCachePropertyBind *bind;
|
||||||
|
|
||||||
widget = g_object_new (ST_TYPE_WIDGET,
|
|
||||||
"opacity", 0,
|
|
||||||
"width", (float)size,
|
|
||||||
"height", (float)size,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
bind = g_slice_new0 (StTextureCachePropertyBind);
|
bind = g_slice_new0 (StTextureCachePropertyBind);
|
||||||
bind->cache = cache;
|
bind->cache = cache;
|
||||||
bind->actor = CLUTTER_ACTOR (widget);
|
|
||||||
bind->size = size;
|
|
||||||
bind->source = object;
|
bind->source = object;
|
||||||
g_object_weak_ref (G_OBJECT (widget), st_texture_cache_bind_weak_notify, bind);
|
|
||||||
bind->weakref_active = TRUE;
|
|
||||||
|
|
||||||
st_texture_cache_reset_texture (bind, property_name);
|
st_texture_cache_reset_texture (bind, property_name);
|
||||||
|
|
||||||
|
g_object_weak_ref (G_OBJECT (bind->image), st_texture_cache_bind_weak_notify, bind);
|
||||||
|
bind->weakref_active = TRUE;
|
||||||
|
|
||||||
notify_key = g_strdup_printf ("notify::%s", property_name);
|
notify_key = g_strdup_printf ("notify::%s", property_name);
|
||||||
bind->notify_signal_id = g_signal_connect_data (object, notify_key, G_CALLBACK(st_texture_cache_on_pixbuf_notify),
|
bind->notify_signal_id = g_signal_connect_data (object, notify_key, G_CALLBACK(st_texture_cache_on_pixbuf_notify),
|
||||||
bind, (GClosureNotify)st_texture_cache_free_bind, 0);
|
bind, (GClosureNotify)st_texture_cache_free_bind, 0);
|
||||||
g_free (notify_key);
|
g_free (notify_key);
|
||||||
|
|
||||||
return widget;
|
return G_ICON (bind->image);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,10 +64,9 @@ st_texture_cache_load_sliced_image (StTextureCache *cache,
|
|||||||
GFunc load_callback,
|
GFunc load_callback,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
|
||||||
StWidget *st_texture_cache_bind_cairo_surface_property (StTextureCache *cache,
|
GIcon *st_texture_cache_bind_cairo_surface_property (StTextureCache *cache,
|
||||||
GObject *object,
|
GObject *object,
|
||||||
const char *property_name,
|
const char *property_name);
|
||||||
gint size);
|
|
||||||
|
|
||||||
ClutterActor *st_texture_cache_load_gicon (StTextureCache *cache,
|
ClutterActor *st_texture_cache_load_gicon (StTextureCache *cache,
|
||||||
StThemeNode *theme_node,
|
StThemeNode *theme_node,
|
||||||
|
Loading…
Reference in New Issue
Block a user