Scale tasklist icons

This commit is contained in:
raveit65 2021-12-12 18:23:30 +01:00
parent 9c564621a9
commit c3c18d64cf
7 changed files with 4205 additions and 1 deletions

View File

@ -3,12 +3,20 @@
Summary: Window Navigator Construction Kit
Name: libwnck3
Version: 40.0
Release: 3%{?dist}
Release: 4%{?dist}
URL: http://download.gnome.org/sources/%{source_name}/
Source0: http://download.gnome.org/sources/%{source_name}/40/%{source_name}-%{version}.tar.xz
License: LGPLv2+
Patch1: libwnck_0001-Revert-pager-do-not-change-workspace-size-from-size_.patch
# https://gitlab.gnome.org/GNOME/libwnck/-/commit/bd8ab37
Patch2: libwnck_0001-xutils-move-WnckIconCache-to-its-own-file.patch
# https://gitlab.gnome.org/GNOME/libwnck/-/merge_requests/10
Patch3: libwnck_0001-Expose-window-scaling-factor.patch
Patch4: libwnck_0002-icons-Use-cairo-surfaces-to-render-icons.patch
Patch5: libwnck_0003-xutils-Change-icons-to-being-cairo-surfaces.patch
Patch6: libwnck_0004-icons-Mark-GdkPixbuf-icons-as-deprecated.patch
Patch7: libwnck_0005-tasklist-Add-surface-loader-function.patch
BuildRequires: gcc
BuildRequires: meson
@ -72,6 +80,10 @@ developing applications that use %{name}.
%changelog
* Sun Dec 12 2021 Wolfgang Ulbrich <fedora@raveit.de> - 40.0-4
- use https://gitlab.gnome.org/GNOME/libwnck/-/commit/bd8ab37
- Scale tasklist icons
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org> - 40.0-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild

View File

@ -0,0 +1,58 @@
From 42c7798ccd4d488a4a927af62f1b8b4e404e9dd4 Mon Sep 17 00:00:00 2001
From: Victor Kareh <vkareh@redhat.com>
Date: Tue, 6 Aug 2019 09:59:59 -0400
Subject: [PATCH 1/5] Expose window scaling factor
---
libwnck/private.h | 2 ++
libwnck/util.c | 21 +++++++++++++++++++++
2 files changed, 23 insertions(+)
diff --git a/libwnck/private.h b/libwnck/private.h
index f1a4af2..199d2b4 100644
--- a/libwnck/private.h
+++ b/libwnck/private.h
@@ -43,6 +43,8 @@ WnckHandle *_wnck_get_handle (void);
WnckClientType _wnck_get_client_type (void);
+int _wnck_get_window_scaling_factor (void);
+
gsize _wnck_get_default_icon_size (void);
gsize _wnck_get_default_mini_icon_size (void);
diff --git a/libwnck/util.c b/libwnck/util.c
index b3d8750..d51ee05 100644
--- a/libwnck/util.c
+++ b/libwnck/util.c
@@ -680,6 +680,27 @@ _wnck_get_client_type (void)
return _wnck_handle_get_client_type (_wnck_get_handle ());
}
+/**
+ * _wnck_get_window_scaling_factor:
+ *
+ * Retrieves the internal scale factor that maps from window coordinates to the
+ * actual device pixels. On traditional systems this is 1, on high density
+ * outputs, it can be a higher value (typically 2).
+ */
+int
+_wnck_get_window_scaling_factor (void)
+{
+ GdkScreen *screen;
+ GValue value = G_VALUE_INIT;
+
+ g_value_init (&value, G_TYPE_INT);
+
+ screen = gdk_screen_get_default ();
+ if (gdk_screen_get_setting (screen, "gdk-window-scaling-factor", &value))
+ return g_value_get_int (&value);
+ return 1;
+}
+
static gsize default_icon_size = WNCK_DEFAULT_ICON_SIZE;
/**
--
2.31.1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,812 @@
From b5db0c72ffcb702f7c277bf46ce0c6585b079b25 Mon Sep 17 00:00:00 2001
From: Victor Kareh <vkareh@redhat.com>
Date: Mon, 20 Jan 2020 13:38:59 -0500
Subject: [PATCH 3/5] xutils: Change icons to being cairo surfaces
Since all icons are stored internally as cairo surfaces, we should be
returning icons as cairo surfaces from the private functions in xutils.
This simplifies the drawing codepath and makes us able to delete a bunch
of GdkPixbuf manipulation.
adapted from https://gitlab.gnome.org/GNOME/mutter/commit/af7f51b9
---
libwnck/application.c | 22 +--
libwnck/class-group.c | 17 +-
libwnck/tasklist.c | 9 +-
libwnck/util.c | 4 +-
libwnck/window.c | 22 +--
libwnck/wnck-icon-cache-private.h | 15 +-
libwnck/wnck-icon-cache.c | 305 +++++++++++++-----------------
libwnck/xutils.c | 42 ++--
libwnck/xutils.h | 11 +-
9 files changed, 186 insertions(+), 261 deletions(-)
diff --git a/libwnck/application.c b/libwnck/application.c
index 66f1502..8d9d034 100644
--- a/libwnck/application.c
+++ b/libwnck/application.c
@@ -323,15 +323,17 @@ wnck_application_get_pid (WnckApplication *app)
static void
get_icons (WnckApplication *app)
{
- GdkPixbuf *icon;
- GdkPixbuf *mini_icon;
+ cairo_surface_t *icon;
+ cairo_surface_t *mini_icon;
gsize normal_size;
gsize mini_size;
+ int scaling_factor;
icon = NULL;
mini_icon = NULL;
normal_size = _wnck_get_default_icon_size ();
mini_size = _wnck_get_default_mini_icon_size ();
+ scaling_factor = _wnck_get_window_scaling_factor ();
if (_wnck_read_icons (app->priv->screen,
app->priv->xwindow,
@@ -339,7 +341,8 @@ get_icons (WnckApplication *app)
&icon,
normal_size,
&mini_icon,
- mini_size))
+ mini_size,
+ scaling_factor))
{
app->priv->need_emit_icon_changed = TRUE;
app->priv->icon_from_leader = TRUE;
@@ -347,17 +350,8 @@ get_icons (WnckApplication *app)
g_clear_pointer (&app->priv->icon, cairo_surface_destroy);
g_clear_pointer (&app->priv->mini_icon, cairo_surface_destroy);
- if (icon)
- {
- app->priv->icon = gdk_cairo_surface_create_from_pixbuf (icon, 0, NULL);
- g_clear_object (&icon);
- }
-
- if (mini_icon)
- {
- app->priv->mini_icon = gdk_cairo_surface_create_from_pixbuf (mini_icon, 0, NULL);
- g_clear_object (&mini_icon);
- }
+ app->priv->icon = icon;
+ app->priv->mini_icon = mini_icon;
}
/* FIXME we should really fall back to using the icon
diff --git a/libwnck/class-group.c b/libwnck/class-group.c
index b0d4fee..dbf5e1d 100644
--- a/libwnck/class-group.c
+++ b/libwnck/class-group.c
@@ -448,23 +448,10 @@ set_icon (WnckClassGroup *class_group)
if (!icon || !mini_icon)
{
- GdkPixbuf *icon_pixbuf, *mini_icon_pixbuf;
-
- _wnck_get_fallback_icons (&icon_pixbuf,
+ _wnck_get_fallback_icons (&icon,
_wnck_get_default_icon_size (),
- &mini_icon_pixbuf,
+ &mini_icon,
_wnck_get_default_mini_icon_size ());
- if (icon_pixbuf)
- {
- icon = gdk_cairo_surface_create_from_pixbuf (icon_pixbuf, 0, NULL);
- g_clear_object (&icon_pixbuf);
- }
-
- if (mini_icon_pixbuf)
- {
- mini_icon = gdk_cairo_surface_create_from_pixbuf (mini_icon_pixbuf, 0, NULL);
- g_clear_object (&mini_icon_pixbuf);
- }
icons_reffed = TRUE;
}
diff --git a/libwnck/tasklist.c b/libwnck/tasklist.c
index 9cb8f0b..b10ef8c 100644
--- a/libwnck/tasklist.c
+++ b/libwnck/tasklist.c
@@ -3694,15 +3694,8 @@ wnck_task_get_icon (WnckTask *task)
if (surface == NULL)
{
- GdkPixbuf *pixbuf;
_wnck_get_fallback_icons (NULL, 0,
- &pixbuf, MINI_ICON_SIZE);
-
- if (pixbuf != NULL)
- {
- surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 0, NULL);
- g_object_unref (pixbuf);
- }
+ &surface, MINI_ICON_SIZE);
}
#endif
break;
diff --git a/libwnck/util.c b/libwnck/util.c
index 8ccce16..d51ee05 100644
--- a/libwnck/util.c
+++ b/libwnck/util.c
@@ -721,7 +721,7 @@ wnck_set_default_icon_size (gsize size)
gsize
_wnck_get_default_icon_size (void)
{
- return default_icon_size * _wnck_get_window_scaling_factor ();
+ return default_icon_size;
}
static gsize default_mini_icon_size = WNCK_DEFAULT_MINI_ICON_SIZE;
@@ -766,7 +766,7 @@ wnck_set_default_mini_icon_size (gsize size)
gsize
_wnck_get_default_mini_icon_size (void)
{
- return default_mini_icon_size * _wnck_get_window_scaling_factor ();
+ return default_mini_icon_size;
}
/**
diff --git a/libwnck/window.c b/libwnck/window.c
index bd8ac31..92f3c08 100644
--- a/libwnck/window.c
+++ b/libwnck/window.c
@@ -2111,15 +2111,17 @@ wnck_window_transient_is_most_recently_activated (WnckWindow *window)
static void
get_icons (WnckWindow *window)
{
- GdkPixbuf *icon;
- GdkPixbuf *mini_icon;
+ cairo_surface_t *icon;
+ cairo_surface_t *mini_icon;
gsize normal_size;
gsize mini_size;
+ int scaling_factor;
icon = NULL;
mini_icon = NULL;
normal_size = _wnck_get_default_icon_size ();
mini_size = _wnck_get_default_mini_icon_size ();
+ scaling_factor = _wnck_get_window_scaling_factor ();
if (_wnck_read_icons (window->priv->screen,
window->priv->xwindow,
@@ -2127,24 +2129,16 @@ get_icons (WnckWindow *window)
&icon,
normal_size,
&mini_icon,
- mini_size))
+ mini_size,
+ scaling_factor))
{
window->priv->need_emit_icon_changed = TRUE;
g_clear_pointer (&window->priv->icon, cairo_surface_destroy);
g_clear_pointer (&window->priv->mini_icon, cairo_surface_destroy);
- if (icon)
- {
- window->priv->icon = gdk_cairo_surface_create_from_pixbuf (icon, 0, NULL);
- g_clear_object (&icon);
- }
-
- if (mini_icon)
- {
- window->priv->mini_icon = gdk_cairo_surface_create_from_pixbuf (mini_icon, 0, NULL);
- g_clear_object (&mini_icon);
- }
+ window->priv->icon = icon;
+ window->priv->mini_icon = mini_icon;
}
g_assert ((window->priv->icon && window->priv->mini_icon) ||
diff --git a/libwnck/wnck-icon-cache-private.h b/libwnck/wnck-icon-cache-private.h
index 6a3d5ec..d3c39e2 100644
--- a/libwnck/wnck-icon-cache-private.h
+++ b/libwnck/wnck-icon-cache-private.h
@@ -38,13 +38,14 @@ void _wnck_icon_cache_set_want_fallback (WnckIconCache *icon_cache
gboolean setting);
gboolean _wnck_icon_cache_get_is_fallback (WnckIconCache *icon_cache);
-gboolean _wnck_read_icons (WnckScreen *screen,
- Window xwindow,
- WnckIconCache *icon_cache,
- GdkPixbuf **iconp,
- int ideal_size,
- GdkPixbuf **mini_iconp,
- int ideal_mini_size);
+gboolean _wnck_read_icons (WnckScreen *screen,
+ Window xwindow,
+ WnckIconCache *icon_cache,
+ cairo_surface_t **iconp,
+ int ideal_size,
+ cairo_surface_t **mini_iconp,
+ int ideal_mini_size,
+ int scaling_factor);
G_END_DECLS
diff --git a/libwnck/wnck-icon-cache.c b/libwnck/wnck-icon-cache.c
index 1749585..38131d8 100644
--- a/libwnck/wnck-icon-cache.c
+++ b/libwnck/wnck-icon-cache.c
@@ -45,8 +45,8 @@ struct _WnckIconCache
IconOrigin origin;
Pixmap prev_pixmap;
Pixmap prev_mask;
- GdkPixbuf *icon;
- GdkPixbuf *mini_icon;
+ cairo_surface_t *icon;
+ cairo_surface_t *mini_icon;
int ideal_size;
int ideal_mini_size;
guint want_fallback : 1;
@@ -141,49 +141,65 @@ find_best_size (gulong *data,
return FALSE;
}
-static void
-argbdata_to_pixdata (gulong *argb_data, int len, guchar **pixdata)
+static cairo_surface_t *
+argbdata_to_surface (gulong *argb_data,
+ int w,
+ int h,
+ int ideal_w,
+ int ideal_h,
+ int scaling_factor)
{
- guchar *p;
- int i;
+ cairo_surface_t *surface, *icon;
+ cairo_t *cr;
+ int y, x, stride;
+ uint32_t *data;
- *pixdata = g_new (guchar, len * 4);
- p = *pixdata;
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
+ cairo_surface_set_device_scale (surface, (double)scaling_factor, (double)scaling_factor);
+ stride = cairo_image_surface_get_stride (surface) / sizeof (uint32_t);
+ data = (uint32_t *) cairo_image_surface_get_data (surface);
/* One could speed this up a lot. */
- i = 0;
- while (i < len)
+ for (y = 0; y < h; y++)
{
- guint argb;
- guint rgba;
-
- argb = argb_data[i];
- rgba = (argb << 8) | (argb >> 24);
-
- *p = rgba >> 24;
- ++p;
- *p = (rgba >> 16) & 0xff;
- ++p;
- *p = (rgba >> 8) & 0xff;
- ++p;
- *p = rgba & 0xff;
- ++p;
-
- ++i;
+ for (x = 0; x < w; x++)
+ {
+ uint32_t *p = &data[y * stride + x];
+ gulong *d = &argb_data[y * w + x];
+ *p = *d;
+ }
}
+
+ cairo_surface_mark_dirty (surface);
+
+ icon = cairo_surface_create_similar_image (surface,
+ cairo_image_surface_get_format (surface),
+ ideal_w, ideal_h);
+
+ cairo_surface_set_device_scale (icon, (double)scaling_factor, (double)scaling_factor);
+
+ cr = cairo_create (icon);
+ cairo_scale (cr, ideal_w / (double)w, ideal_h / (double)h);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_IN);
+ cairo_paint (cr);
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (surface);
+
+ return icon;
}
static gboolean
-read_rgb_icon (Screen *screen,
- Window xwindow,
- int ideal_size,
- int ideal_mini_size,
- int *width,
- int *height,
- guchar **pixdata,
- int *mini_width,
- int *mini_height,
- guchar **mini_pixdata)
+read_rgb_icon (Screen *screen,
+ Window xwindow,
+ int ideal_size,
+ int ideal_mini_size,
+ cairo_surface_t **iconp,
+ cairo_surface_t **mini_iconp,
+ int scaling_factor)
{
Display *display;
Atom type;
@@ -221,7 +237,9 @@ read_rgb_icon (Screen *screen,
return FALSE;
}
- if (!find_best_size (data, nitems, ideal_size, &w, &h, &best))
+ if (!find_best_size (data, nitems,
+ ideal_size,
+ &w, &h, &best))
{
XFree (data);
return FALSE;
@@ -235,14 +253,8 @@ read_rgb_icon (Screen *screen,
return FALSE;
}
- *width = w;
- *height = h;
-
- *mini_width = mini_w;
- *mini_height = mini_h;
-
- argbdata_to_pixdata (best, w * h, pixdata);
- argbdata_to_pixdata (best_mini, mini_w * mini_h, mini_pixdata);
+ *iconp = argbdata_to_surface (best, w, h, ideal_size, ideal_size, scaling_factor);
+ *mini_iconp = argbdata_to_surface (best_mini, mini_w, mini_h, ideal_mini_size, ideal_mini_size, scaling_factor);
XFree (data);
@@ -250,27 +262,27 @@ read_rgb_icon (Screen *screen,
}
static gboolean
-try_pixmap_and_mask (Screen *screen,
- Pixmap src_pixmap,
- Pixmap src_mask,
- GdkPixbuf **iconp,
- int ideal_size,
- GdkPixbuf **mini_iconp,
- int ideal_mini_size)
+try_pixmap_and_mask (Screen *screen,
+ Pixmap src_pixmap,
+ Pixmap src_mask,
+ cairo_surface_t **iconp,
+ int ideal_size,
+ cairo_surface_t **mini_iconp,
+ int ideal_mini_size,
+ int scaling_factor)
{
cairo_surface_t *surface, *mask_surface, *image;
GdkDisplay *gdk_display;
- GdkPixbuf *unscaled;
int width, height;
cairo_t *cr;
if (src_pixmap == None)
return FALSE;
- surface = _wnck_cairo_surface_get_from_pixmap (screen, src_pixmap);
+ surface = _wnck_cairo_surface_get_from_pixmap (screen, src_pixmap, scaling_factor);
if (surface && src_mask != None)
- mask_surface = _wnck_cairo_surface_get_from_pixmap (screen, src_mask);
+ mask_surface = _wnck_cairo_surface_get_from_pixmap (screen, src_mask, scaling_factor);
else
mask_surface = NULL;
@@ -326,26 +338,41 @@ try_pixmap_and_mask (Screen *screen,
return FALSE;
}
- unscaled = gdk_pixbuf_get_from_surface (image,
- 0, 0,
- width, height);
+ if (image)
+ {
+ int image_w, image_h;
- cairo_surface_destroy (image);
+ image_w = cairo_image_surface_get_width (image);
+ image_h = cairo_image_surface_get_height (image);
+
+ *iconp = cairo_surface_create_similar (image,
+ cairo_surface_get_content (image),
+ ideal_size,
+ ideal_size);
+
+ cairo_surface_set_device_scale (*iconp, (double)scaling_factor, (double)scaling_factor);
+
+ cr = cairo_create (*iconp);
+ cairo_scale (cr, ideal_size / (double)image_w, ideal_size / (double)image_h);
+ cairo_set_source_surface (cr, image, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ *mini_iconp = cairo_surface_create_similar (image,
+ cairo_surface_get_content (image),
+ ideal_mini_size,
+ ideal_mini_size);
+
+ cairo_surface_set_device_scale (*mini_iconp, (double)scaling_factor, (double)scaling_factor);
+
+ cr = cairo_create (*mini_iconp);
+ cairo_scale (cr, ideal_mini_size / (double)image_w, ideal_mini_size / (double)image_h);
+ cairo_set_source_surface (cr, image, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (image);
- if (unscaled)
- {
- *iconp =
- gdk_pixbuf_scale_simple (unscaled,
- ideal_size,
- ideal_size,
- GDK_INTERP_BILINEAR);
- *mini_iconp =
- gdk_pixbuf_scale_simple (unscaled,
- ideal_mini_size,
- ideal_mini_size,
- GDK_INTERP_BILINEAR);
-
- g_object_unref (G_OBJECT (unscaled));
return TRUE;
}
else
@@ -404,13 +431,8 @@ static void
clear_icon_cache (WnckIconCache *icon_cache,
gboolean dirty_all)
{
- if (icon_cache->icon)
- g_object_unref (G_OBJECT (icon_cache->icon));
- icon_cache->icon = NULL;
-
- if (icon_cache->mini_icon)
- g_object_unref (G_OBJECT (icon_cache->mini_icon));
- icon_cache->mini_icon = NULL;
+ g_clear_pointer (&icon_cache->icon, cairo_surface_destroy);
+ g_clear_pointer (&icon_cache->mini_icon, cairo_surface_destroy);
icon_cache->origin = USING_NO_ICON;
@@ -423,89 +445,26 @@ clear_icon_cache (WnckIconCache *icon_cache,
}
static void
-replace_cache (WnckIconCache *icon_cache,
- IconOrigin origin,
- GdkPixbuf *new_icon,
- GdkPixbuf *new_mini_icon)
+replace_cache (WnckIconCache *icon_cache,
+ IconOrigin origin,
+ cairo_surface_t *new_icon,
+ cairo_surface_t *new_mini_icon)
{
clear_icon_cache (icon_cache, FALSE);
icon_cache->origin = origin;
if (new_icon)
- g_object_ref (G_OBJECT (new_icon));
+ cairo_surface_reference (new_icon);
icon_cache->icon = new_icon;
if (new_mini_icon)
- g_object_ref (G_OBJECT (new_mini_icon));
+ cairo_surface_reference (new_mini_icon);
icon_cache->mini_icon = new_mini_icon;
}
-static void
-free_pixels (guchar *pixels,
- gpointer data)
-{
- g_free (pixels);
-}
-
-static GdkPixbuf*
-scaled_from_pixdata (guchar *pixdata,
- int w,
- int h,
- int new_w,
- int new_h)
-{
- GdkPixbuf *src;
- GdkPixbuf *dest;
-
- src = gdk_pixbuf_new_from_data (pixdata,
- GDK_COLORSPACE_RGB,
- TRUE,
- 8,
- w, h, w * 4,
- free_pixels,
- NULL);
-
- if (src == NULL)
- return NULL;
-
- if (w != h)
- {
- GdkPixbuf *tmp;
- int size;
-
- size = MAX (w, h);
-
- tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, size, size);
-
- if (tmp != NULL)
- {
- gdk_pixbuf_fill (tmp, 0);
- gdk_pixbuf_copy_area (src, 0, 0, w, h,
- tmp,
- (size - w) / 2, (size - h) / 2);
-
- g_object_unref (src);
- src = tmp;
- }
- }
-
- if (w != new_w || h != new_h)
- {
- dest = gdk_pixbuf_scale_simple (src, new_w, new_h, GDK_INTERP_BILINEAR);
-
- g_object_unref (G_OBJECT (src));
- }
- else
- {
- dest = src;
- }
-
- return dest;
-}
-
WnckIconCache*
_wnck_icon_cache_new (void)
{
@@ -585,22 +544,17 @@ _wnck_icon_cache_get_is_fallback (WnckIconCache *icon_cache)
}
gboolean
-_wnck_read_icons (WnckScreen *screen,
- Window xwindow,
- WnckIconCache *icon_cache,
- GdkPixbuf **iconp,
- int ideal_size,
- GdkPixbuf **mini_iconp,
- int ideal_mini_size)
+_wnck_read_icons (WnckScreen *screen,
+ Window xwindow,
+ WnckIconCache *icon_cache,
+ cairo_surface_t **iconp,
+ int ideal_size,
+ cairo_surface_t **mini_iconp,
+ int ideal_mini_size,
+ int scaling_factor)
{
Screen *xscreen;
Display *display;
- guchar *pixdata;
- int w, h;
- guchar *mini_pixdata;
- int mini_w, mini_h;
- Pixmap pixmap;
- Pixmap mask;
XWMHints *hints;
/* Return value is whether the icon changed */
@@ -613,6 +567,9 @@ _wnck_read_icons (WnckScreen *screen,
*iconp = NULL;
*mini_iconp = NULL;
+ ideal_size *= scaling_factor;
+ ideal_mini_size *= scaling_factor;
+
if (ideal_size != icon_cache->ideal_size ||
ideal_mini_size != icon_cache->ideal_mini_size)
clear_icon_cache (icon_cache, TRUE);
@@ -623,8 +580,6 @@ _wnck_read_icons (WnckScreen *screen,
if (!_wnck_icon_cache_get_icon_invalidated (icon_cache))
return FALSE; /* we have no new info to use */
- pixdata = NULL;
-
/* Our algorithm here assumes that we can't have for example origin
* < USING_NET_WM_ICON and icon_cache->net_wm_icon_dirty == FALSE
* unless we have tried to read NET_WM_ICON.
@@ -636,21 +591,15 @@ _wnck_read_icons (WnckScreen *screen,
if (icon_cache->origin <= USING_NET_WM_ICON &&
icon_cache->net_wm_icon_dirty)
-
{
icon_cache->net_wm_icon_dirty = FALSE;
if (read_rgb_icon (xscreen, xwindow,
ideal_size,
ideal_mini_size,
- &w, &h, &pixdata,
- &mini_w, &mini_h, &mini_pixdata))
+ iconp, mini_iconp,
+ scaling_factor))
{
- *iconp = scaled_from_pixdata (pixdata, w, h, ideal_size, ideal_size);
-
- *mini_iconp = scaled_from_pixdata (mini_pixdata, mini_w, mini_h,
- ideal_mini_size, ideal_mini_size);
-
replace_cache (icon_cache, USING_NET_WM_ICON,
*iconp, *mini_iconp);
@@ -661,6 +610,9 @@ _wnck_read_icons (WnckScreen *screen,
if (icon_cache->origin <= USING_WM_HINTS &&
icon_cache->wm_hints_dirty)
{
+ Pixmap pixmap;
+ Pixmap mask;
+
icon_cache->wm_hints_dirty = FALSE;
_wnck_error_trap_push (display);
@@ -689,7 +641,8 @@ _wnck_read_icons (WnckScreen *screen,
{
if (try_pixmap_and_mask (xscreen, pixmap, mask,
iconp, ideal_size,
- mini_iconp, ideal_mini_size))
+ mini_iconp, ideal_mini_size,
+ scaling_factor))
{
icon_cache->prev_pixmap = pixmap;
icon_cache->prev_mask = mask;
@@ -705,6 +658,9 @@ _wnck_read_icons (WnckScreen *screen,
if (icon_cache->origin <= USING_KWM_WIN_ICON &&
icon_cache->kwm_win_icon_dirty)
{
+ Pixmap pixmap;
+ Pixmap mask;
+
icon_cache->kwm_win_icon_dirty = FALSE;
get_kwm_win_icon (xscreen, xwindow, &pixmap, &mask);
@@ -715,7 +671,8 @@ _wnck_read_icons (WnckScreen *screen,
{
if (try_pixmap_and_mask (xscreen, pixmap, mask,
iconp, ideal_size,
- mini_iconp, ideal_mini_size))
+ mini_iconp, ideal_mini_size,
+ scaling_factor))
{
icon_cache->prev_pixmap = pixmap;
icon_cache->prev_mask = mask;
diff --git a/libwnck/xutils.c b/libwnck/xutils.c
index 58873dc..cd9036a 100644
--- a/libwnck/xutils.c
+++ b/libwnck/xutils.c
@@ -1453,7 +1453,8 @@ _wnck_select_input (Screen *screen,
cairo_surface_t *
_wnck_cairo_surface_get_from_pixmap (Screen *screen,
- Pixmap xpixmap)
+ Pixmap xpixmap,
+ int scaling_factor)
{
cairo_surface_t *surface;
Display *display;
@@ -1471,6 +1472,9 @@ _wnck_cairo_surface_get_from_pixmap (Screen *screen,
&x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
goto TRAP_POP;
+ w_ret *= scaling_factor;
+ h_ret *= scaling_factor;
+
if (depth_ret == 1)
{
surface = cairo_xlib_surface_create_for_bitmap (display,
@@ -1527,7 +1531,7 @@ _wnck_gdk_pixbuf_get_from_pixmap (Screen *screen,
cairo_surface_t *surface;
GdkPixbuf *retval;
- surface = _wnck_cairo_surface_get_from_pixmap (screen, xpixmap);
+ surface = _wnck_cairo_surface_get_from_pixmap (screen, xpixmap, 1);
if (surface == NULL)
return NULL;
@@ -1542,36 +1546,30 @@ _wnck_gdk_pixbuf_get_from_pixmap (Screen *screen,
return retval;
}
-static GdkPixbuf*
+static cairo_surface_t*
default_icon_at_size (int size)
{
- GdkPixbuf *base;
+ GdkPixbuf *pixbuf;
+ cairo_surface_t *surface;
- base = gdk_pixbuf_new_from_resource ("/org/gnome/libwnck/default_icon.png", NULL);
+ pixbuf = gdk_pixbuf_new_from_resource_at_scale ("/org/gnome/libwnck/default_icon.png",
+ size, size,
+ TRUE, NULL);
- g_assert (base);
+ g_assert (pixbuf);
- if (gdk_pixbuf_get_width (base) == size &&
- gdk_pixbuf_get_height (base) == size)
- {
- return base;
- }
- else
- {
- GdkPixbuf *scaled;
+ surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 0, NULL);
- scaled = gdk_pixbuf_scale_simple (base, size, size, GDK_INTERP_BILINEAR);
- g_object_unref (G_OBJECT (base));
+ g_clear_object (&pixbuf);
- return scaled;
- }
+ return surface;
}
void
-_wnck_get_fallback_icons (GdkPixbuf **iconp,
- int ideal_size,
- GdkPixbuf **mini_iconp,
- int ideal_mini_size)
+_wnck_get_fallback_icons (cairo_surface_t **iconp,
+ int ideal_size,
+ cairo_surface_t **mini_iconp,
+ int ideal_mini_size)
{
if (iconp)
*iconp = default_icon_at_size (ideal_size);
diff --git a/libwnck/xutils.h b/libwnck/xutils.h
index 2af255d..8146cda 100644
--- a/libwnck/xutils.h
+++ b/libwnck/xutils.h
@@ -159,10 +159,10 @@ void _wnck_keyboard_size (WnckScreen *screen,
void _wnck_toggle_showing_desktop (Screen *screen,
gboolean show);
-void _wnck_get_fallback_icons (GdkPixbuf **iconp,
- int ideal_size,
- GdkPixbuf **mini_iconp,
- int ideal_mini_size);
+void _wnck_get_fallback_icons (cairo_surface_t **iconp,
+ int ideal_size,
+ cairo_surface_t **mini_iconp,
+ int ideal_mini_size);
void _wnck_get_window_geometry (Screen *screen,
Window xwindow,
@@ -195,7 +195,8 @@ void _wnck_set_desktop_layout (Screen *xscreen,
int columns);
cairo_surface_t *_wnck_cairo_surface_get_from_pixmap (Screen *screen,
- Pixmap xpixmap);
+ Pixmap xpixmap,
+ int scaling_factor);
GdkPixbuf* _wnck_gdk_pixbuf_get_from_pixmap (Screen *screen,
Pixmap xpixmap);
--
2.31.1

View File

@ -0,0 +1,189 @@
From af4bab0581f164a0cfb0396591940b26584281c1 Mon Sep 17 00:00:00 2001
From: Victor Kareh <vkareh@redhat.com>
Date: Tue, 11 Feb 2020 07:40:47 -0500
Subject: [PATCH 4/5] icons: Mark GdkPixbuf icons as deprecated
Since we have migrated icons to render as cairo surfaces we can now mark
GdkPixbuf icons as deprecated without having to break the API.
---
libwnck/application.c | 8 ++++++++
libwnck/application.h | 6 ++++++
libwnck/class-group.c | 4 ++++
libwnck/class-group.h | 4 ++++
libwnck/test-wnck.c | 2 +-
libwnck/window.c | 6 ++++++
libwnck/window.h | 4 ++++
7 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/libwnck/application.c b/libwnck/application.c
index 8d9d034..90eee73 100644
--- a/libwnck/application.c
+++ b/libwnck/application.c
@@ -408,6 +408,8 @@ find_icon_window (WnckApplication *app)
* Return value: (transfer none): the icon for @app. The caller should
* reference the returned <classname>GdkPixbuf</classname> if it needs to keep
* the icon around.
+ *
+ * Deprecated:41.0: Use wnck_application_get_icon_surface() instead.
**/
GdkPixbuf*
wnck_application_get_icon (WnckApplication *app)
@@ -447,10 +449,12 @@ wnck_application_get_icon (WnckApplication *app)
}
else
{
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
WnckWindow *w = find_icon_window (app);
if (w)
return wnck_window_get_icon (w);
else
+G_GNUC_END_IGNORE_DEPRECATIONS
return NULL;
}
}
@@ -466,6 +470,8 @@ wnck_application_get_icon (WnckApplication *app)
* Return value: (transfer none): the mini-icon for @app. The caller should
* reference the returned <classname>GdkPixbuf</classname> if it needs to keep
* the mini-icon around.
+ *
+ * Deprecated:41.0: Use wnck_application_get_mini_icon_surface() instead.
**/
GdkPixbuf*
wnck_application_get_mini_icon (WnckApplication *app)
@@ -505,10 +511,12 @@ wnck_application_get_mini_icon (WnckApplication *app)
}
else
{
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
WnckWindow *w = find_icon_window (app);
if (w)
return wnck_window_get_mini_icon (w);
else
+G_GNUC_END_IGNORE_DEPRECATIONS
return NULL;
}
}
diff --git a/libwnck/application.h b/libwnck/application.h
index e8893f5..fbb2442 100644
--- a/libwnck/application.h
+++ b/libwnck/application.h
@@ -90,10 +90,16 @@ int wnck_application_get_n_windows (WnckApplication *app);
const char* wnck_application_get_name (WnckApplication *app);
const char* wnck_application_get_icon_name (WnckApplication *app);
int wnck_application_get_pid (WnckApplication *app);
+
+G_DEPRECATED_FOR(wnck_application_get_icon_surface)
GdkPixbuf* wnck_application_get_icon (WnckApplication *app);
+
+G_DEPRECATED_FOR(wnck_application_get_mini_icon_surface)
GdkPixbuf* wnck_application_get_mini_icon (WnckApplication *app);
+
cairo_surface_t* wnck_application_get_icon_surface (WnckApplication *app);
cairo_surface_t* wnck_application_get_mini_icon_surface (WnckApplication *app);
+
gboolean wnck_application_get_icon_is_fallback (WnckApplication *app);
const char* wnck_application_get_startup_id (WnckApplication *app);
diff --git a/libwnck/class-group.c b/libwnck/class-group.c
index dbf5e1d..9ec6ea6 100644
--- a/libwnck/class-group.c
+++ b/libwnck/class-group.c
@@ -696,6 +696,8 @@ wnck_class_group_get_name (WnckClassGroup *class_group)
* the icon around.
*
* Since: 2.2
+ *
+ * Deprecated:41.0: Use wnck_class_group_get_icon_surface() instead.
**/
GdkPixbuf *
wnck_class_group_get_icon (WnckClassGroup *class_group)
@@ -748,6 +750,8 @@ wnck_class_group_get_icon (WnckClassGroup *class_group)
* to keep the mini-icon around.
*
* Since: 2.2
+ *
+ * Deprecated:41.0: Use wnck_class_group_get_mini_icon_surface() instead.
**/
GdkPixbuf *
wnck_class_group_get_mini_icon (WnckClassGroup *class_group)
diff --git a/libwnck/class-group.h b/libwnck/class-group.h
index 5a9e07c..1370ca6 100644
--- a/libwnck/class-group.h
+++ b/libwnck/class-group.h
@@ -80,8 +80,12 @@ const char * wnck_class_group_get_id (WnckClassGroup *class_group);
const char * wnck_class_group_get_name (WnckClassGroup *class_group);
+G_DEPRECATED_FOR(wnck_class_group_get_icon_surface)
GdkPixbuf *wnck_class_group_get_icon (WnckClassGroup *class_group);
+
+G_DEPRECATED_FOR(wnck_class_group_get_mini_icon_surface)
GdkPixbuf *wnck_class_group_get_mini_icon (WnckClassGroup *class_group);
+
cairo_surface_t *wnck_class_group_get_icon_surface (WnckClassGroup *class_group);
cairo_surface_t *wnck_class_group_get_mini_icon_surface (WnckClassGroup *class_group);
diff --git a/libwnck/test-wnck.c b/libwnck/test-wnck.c
index ffaad59..05ddd7e 100644
--- a/libwnck/test-wnck.c
+++ b/libwnck/test-wnck.c
@@ -520,7 +520,7 @@ icon_set_func (GtkTreeViewColumn *tree_column,
return;
g_object_set (GTK_CELL_RENDERER (cell),
- "pixbuf", wnck_window_get_mini_icon (window),
+ "surface", wnck_window_get_mini_icon_surface (window),
NULL);
}
diff --git a/libwnck/window.c b/libwnck/window.c
index 92f3c08..021dea8 100644
--- a/libwnck/window.c
+++ b/libwnck/window.c
@@ -21,6 +21,8 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
+#undef WNCK_DISABLE_DEPRECATED
+
#include <config.h>
#include <glib/gi18n-lib.h>
@@ -2168,6 +2170,8 @@ _wnck_window_load_icons (WnckWindow *window)
* Return value: (transfer none): the icon for @window. The caller should
* reference the returned <classname>GdkPixbuf</classname> if it needs to keep
* the icon around.
+ *
+ * Deprecated:41.0: Use wnck_window_get_icon_surface() instead.
**/
GdkPixbuf*
wnck_window_get_icon (WnckWindow *window)
@@ -2220,6 +2224,8 @@ wnck_window_get_icon (WnckWindow *window)
* Return value: (transfer none): the mini-icon for @window. The caller should
* reference the returned <classname>GdkPixbuf</classname> if it needs to keep
* the icon around.
+ *
+ * Deprecated:41.0: Use wnck_window_get_mini_icon_surface() instead.
**/
GdkPixbuf*
wnck_window_get_mini_icon (WnckWindow *window)
diff --git a/libwnck/window.h b/libwnck/window.h
index fb3ce51..831024c 100644
--- a/libwnck/window.h
+++ b/libwnck/window.h
@@ -380,8 +380,12 @@ void wnck_window_activate_transient (WnckWindow *window,
guint32 timestamp);
gboolean wnck_window_transient_is_most_recently_activated (WnckWindow *window);
+G_DEPRECATED_FOR(wnck_window_get_icon_surface)
GdkPixbuf* wnck_window_get_icon (WnckWindow *window);
+
+G_DEPRECATED_FOR(wnck_window_get_mini_icon_surface)
GdkPixbuf* wnck_window_get_mini_icon (WnckWindow *window);
+
cairo_surface_t* wnck_window_get_icon_surface (WnckWindow *window);
cairo_surface_t* wnck_window_get_mini_icon_surface (WnckWindow *window);
--
2.31.1

View File

@ -0,0 +1,134 @@
From 4bc5ffe67b88fe47b283cf1b59b3bcd4f18eb105 Mon Sep 17 00:00:00 2001
From: Victor Kareh <vkareh@redhat.com>
Date: Thu, 3 Jun 2021 14:04:06 -0400
Subject: [PATCH 5/5] tasklist: Add surface loader function
Since the tasklist now supports cairo_surface_t icons, we provide
a similar icon loader function that takes surface icons.
---
libwnck/tasklist.c | 50 +++++++++++++++++++++++++++++++++++++++++++++-
libwnck/tasklist.h | 26 ++++++++++++++++++++++++
2 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/libwnck/tasklist.c b/libwnck/tasklist.c
index b10ef8c..9c921b0 100644
--- a/libwnck/tasklist.c
+++ b/libwnck/tasklist.c
@@ -228,6 +228,10 @@ struct _WnckTasklistPrivate
void *icon_loader_data;
GDestroyNotify free_icon_loader_data;
+ WnckLoadSurfaceFunction surface_loader;
+ void *surface_loader_data;
+ GDestroyNotify free_surface_loader_data;
+
#ifdef HAVE_STARTUP_NOTIFICATION
SnMonitorContext *sn_context;
guint startup_sequence_timeout;
@@ -1077,6 +1081,11 @@ wnck_tasklist_finalize (GObject *object)
tasklist->priv->free_icon_loader_data = NULL;
tasklist->priv->icon_loader_data = NULL;
+ if (tasklist->priv->free_surface_loader_data != NULL)
+ (* tasklist->priv->free_surface_loader_data) (tasklist->priv->surface_loader_data);
+ tasklist->priv->free_surface_loader_data = NULL;
+ tasklist->priv->surface_loader_data = NULL;
+
G_OBJECT_CLASS (wnck_tasklist_parent_class)->finalize (object);
}
@@ -1315,6 +1324,31 @@ wnck_tasklist_set_icon_loader (WnckTasklist *tasklist,
tasklist->priv->free_icon_loader_data = free_data_func;
}
+/**
+ * wnck_tasklist_set_surface_loader:
+ * @tasklist: a #WnckTasklist
+ * @load_surface_func: icon loader function
+ * @data: data for icon loader function
+ * @free_data_func: function to free the data
+ *
+ * Sets a function to be used for loading cairo surface icons.
+ **/
+void
+wnck_tasklist_set_surface_loader (WnckTasklist *tasklist,
+ WnckLoadSurfaceFunction load_surface_func,
+ void *data,
+ GDestroyNotify free_data_func)
+{
+ g_return_if_fail (WNCK_IS_TASKLIST (tasklist));
+
+ if (tasklist->priv->free_surface_loader_data != NULL)
+ (* tasklist->priv->free_surface_loader_data) (tasklist->priv->surface_loader_data);
+
+ tasklist->priv->surface_loader = load_surface_func;
+ tasklist->priv->surface_loader_data = data;
+ tasklist->priv->free_surface_loader_data = free_data_func;
+}
+
static void
get_layout (GtkOrientation orientation,
int for_size,
@@ -3665,7 +3699,21 @@ wnck_task_get_icon (WnckTask *task)
case WNCK_TASK_STARTUP_SEQUENCE:
#ifdef HAVE_STARTUP_NOTIFICATION
- if (task->tasklist->priv->icon_loader != NULL)
+ if (task->tasklist->priv->surface_loader != NULL)
+ {
+ const char *icon;
+
+ icon = sn_startup_sequence_get_icon_name (task->startup_sequence);
+ if (icon != NULL)
+ {
+ surface = (* task->tasklist->priv->surface_loader) (icon,
+ MINI_ICON_SIZE,
+ 0,
+ task->tasklist->priv->surface_loader_data);
+
+ }
+ }
+ else if (task->tasklist->priv->icon_loader != NULL)
{
const char *icon;
diff --git a/libwnck/tasklist.h b/libwnck/tasklist.h
index 0659f9d..0af8df5 100644
--- a/libwnck/tasklist.h
+++ b/libwnck/tasklist.h
@@ -138,6 +138,32 @@ void wnck_tasklist_set_icon_loader (WnckTasklist *tasklist,
void *data,
GDestroyNotify free_data_func);
+/**
+ * WnckLoadSurfaceFunction:
+ * @icon_name: an icon name as in the Icon field in a .desktop file for the
+ * icon to load.
+ * @size: the desired icon size.
+ * @flags: not defined to do anything yet.
+ * @data: data passed to the function, set when the #WnckLoadSurfaceFunction has
+ * been set for the #WnckTasklist.
+ *
+ * Specifies the type of function passed to wnck_tasklist_set_icon_loader().
+ *
+ * Returns: it should return a <classname>cairo_surface_t</classname> of @icon_name
+ * at size @size, or %NULL if no icon for @icon_name at size @size could be
+ * loaded.
+ *
+ */
+typedef cairo_surface_t* (*WnckLoadSurfaceFunction) (const char *icon_name,
+ int size,
+ unsigned int flags,
+ void *data);
+
+void wnck_tasklist_set_surface_loader (WnckTasklist *tasklist,
+ WnckLoadSurfaceFunction load_surface_func,
+ void *data,
+ GDestroyNotify free_data_func);
+
G_END_DECLS
#endif /* WNCK_TASKLIST_H */
--
2.31.1