diff --git a/SPECS-EXTENDED/libwnck3/libwnck3.signatures.json b/SPECS-EXTENDED/libwnck3/libwnck3.signatures.json index 83eb52a385f..343e0429509 100644 --- a/SPECS-EXTENDED/libwnck3/libwnck3.signatures.json +++ b/SPECS-EXTENDED/libwnck3/libwnck3.signatures.json @@ -1,5 +1,5 @@ { "Signatures": { - "libwnck-3.36.0.tar.xz": "bc508150b3ed5d22354b0e6774ad4eee465381ebc0ace45eb0e2d3a4186c925f" + "libwnck-43.1.tar.xz": "634b4587b7367a493d3818c4b57740dac06153cf8f25cd64f5af16b657dd6845" } -} +} \ No newline at end of file diff --git a/SPECS-EXTENDED/libwnck3/libwnck3.spec b/SPECS-EXTENDED/libwnck3/libwnck3.spec index 72ae6fb484f..ea110e3caa9 100644 --- a/SPECS-EXTENDED/libwnck3/libwnck3.spec +++ b/SPECS-EXTENDED/libwnck3/libwnck3.spec @@ -1,22 +1,30 @@ Vendor: Microsoft Corporation Distribution: Azure Linux +# SPDX-License-Identifier: LGPL-2.0-or-later %global source_name libwnck Summary: Window Navigator Construction Kit Name: libwnck3 -Version: 3.36.0 -Release: 3%{?dist} +Version: 43.1 +Release: 1%{?dist} URL: http://download.gnome.org/sources/%{source_name}/ -Source0: http://download.gnome.org/sources/%{source_name}/3.36/%{source_name}-%{version}.tar.xz -License: GPLv2 +Source0: http://download.gnome.org/sources/%{source_name}/43/%{source_name}-%{version}.tar.xz +License: LGPL-2.0-or-later + +# https://gitlab.gnome.org/GNOME/libwnck/-/merge_requests/10 +Patch1: libwnck_0001-Expose-window-scaling-factor_v43.1.patch +Patch2: libwnck_0002-icons-Use-cairo-surfaces-to-render-icons_v43.1.patch +Patch3: libwnck_0003-xutils-Change-icons-to-being-cairo-surfaces_v43.1.patch +Patch4: libwnck_0004-icons-Mark-GdkPixbuf-icons-as-deprecated_v43.1.patch +Patch5: libwnck_0005-tasklist-Add-surface-loader-function_v43.1.patch -BuildRequires: %{_bindir}/xsltproc BuildRequires: gcc BuildRequires: meson BuildRequires: gettext BuildRequires: glib2-devel BuildRequires: gobject-introspection-devel BuildRequires: gtk3-devel +BuildRequires: gtk-doc BuildRequires: libXres-devel BuildRequires: pango-devel BuildRequires: startup-notification-devel @@ -38,11 +46,11 @@ developing applications that use %{name}. %prep -%setup -q -n %{source_name}-%{version} +%autosetup -n %{source_name}-%{version} -p1 %build -%meson -Dgtk_doc=false +%meson -Dgtk_doc=true %meson_build @@ -58,7 +66,7 @@ developing applications that use %{name}. %files -f %{source_name}-3.0.lang %license COPYING %doc AUTHORS README NEWS -%{_libdir}/%{source_name}-3.so.* +%{_libdir}/%{source_name}-3.so.0* %{_bindir}/wnck-urgency-monitor %{_libdir}/girepository-1.0/Wnck-3.0.typelib @@ -68,9 +76,14 @@ developing applications that use %{name}. %{_libdir}/pkgconfig/* %{_includedir}/%{source_name}-3.0/ %{_datadir}/gir-1.0/Wnck-3.0.gir +%doc %{_datadir}/gtk-doc %changelog +* Mon Nov 18 2024 Sreenivasulu Malavathula - 43.1-1 +- Update Azure-Linux import from Fedora 41 (license: LGPL-2.0-r-later). +- License verified. + * Mon Mar 21 2022 Pawel Winogrodzki - 3.36.0-3 - Adding BR on '%%{_bindir}/xsltproc'. - Disabled gtk doc generation to remove network dependency during build-time. diff --git a/SPECS-EXTENDED/libwnck3/libwnck_0001-Expose-window-scaling-factor_v43.1.patch b/SPECS-EXTENDED/libwnck3/libwnck_0001-Expose-window-scaling-factor_v43.1.patch new file mode 100644 index 00000000000..322c1cbb1be --- /dev/null +++ b/SPECS-EXTENDED/libwnck3/libwnck_0001-Expose-window-scaling-factor_v43.1.patch @@ -0,0 +1,58 @@ +From 18398f3a78b3fe71e99b2da9258cb793b0809bad Mon Sep 17 00:00:00 2001 +From: Victor Kareh +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 bf87619..0d88ddd 100644 +--- a/libwnck/private.h ++++ b/libwnck/private.h +@@ -37,6 +37,8 @@ G_BEGIN_DECLS + + WnckHandle *_wnck_get_handle (void); + ++int _wnck_get_window_scaling_factor (void); ++ + void _wnck_application_process_property_notify (WnckApplication *app, + XEvent *xevent); + void _wnck_window_process_property_notify (WnckWindow *window, +diff --git a/libwnck/util.c b/libwnck/util.c +index 83659dc..a58a99e 100644 +--- a/libwnck/util.c ++++ b/libwnck/util.c +@@ -164,6 +164,27 @@ _wnck_get_handle (void) + return wnck_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; ++} ++ + /** + * wnck_set_default_icon_size: + * @size: the default size for windows and application standard icons. +-- +2.46.1 + diff --git a/SPECS-EXTENDED/libwnck3/libwnck_0002-icons-Use-cairo-surfaces-to-render-icons_v43.1.patch b/SPECS-EXTENDED/libwnck3/libwnck_0002-icons-Use-cairo-surfaces-to-render-icons_v43.1.patch new file mode 100644 index 00000000000..dbec06525a7 --- /dev/null +++ b/SPECS-EXTENDED/libwnck3/libwnck_0002-icons-Use-cairo-surfaces-to-render-icons_v43.1.patch @@ -0,0 +1,1355 @@ +From 476e87b5e5a57ebbf0912e9f4121cef5d0fd7582 Mon Sep 17 00:00:00 2001 +From: Victor Kareh +Date: Fri, 27 Nov 2020 11:25:08 -0500 +Subject: [PATCH 2/5] icons: Use cairo surfaces to render icons + +This replaces GdkPixbuf manipulation with the cairo_surface equivalents. +As a result, icons can now render sharply in HiDPI displays. +--- + libwnck/application.c | 151 ++++++++++++++++++--- + libwnck/application.h | 3 + + libwnck/class-group.c | 171 +++++++++++++++++++----- + libwnck/class-group.h | 3 + + libwnck/pager.c | 20 +-- + libwnck/selector.c | 103 +++++++-------- + libwnck/tasklist.c | 173 ++++++++++++------------- + libwnck/util.c | 12 ++ + libwnck/window.c | 139 +++++++++++++++++--- + libwnck/window.h | 3 + + libwnck/wnck-image-menu-item-private.h | 3 + + libwnck/wnck-image-menu-item.c | 8 ++ + 12 files changed, 565 insertions(+), 224 deletions(-) + +diff --git a/libwnck/application.c b/libwnck/application.c +index 094cd9e..77958c4 100644 +--- a/libwnck/application.c ++++ b/libwnck/application.c +@@ -62,8 +62,8 @@ struct _WnckApplicationPrivate + + WnckWindow *name_window; /* window we are using name of */ + +- GdkPixbuf *icon; +- GdkPixbuf *mini_icon; ++ cairo_surface_t *icon; ++ cairo_surface_t *mini_icon; + + WnckIconCache *icon_cache; + +@@ -159,13 +159,8 @@ wnck_application_finalize (GObject *object) + g_free (application->priv->name); + application->priv->name = NULL; + +- if (application->priv->icon) +- g_object_unref (G_OBJECT (application->priv->icon)); +- application->priv->icon = NULL; +- +- if (application->priv->mini_icon) +- g_object_unref (G_OBJECT (application->priv->mini_icon)); +- application->priv->mini_icon = NULL; ++ g_clear_pointer (&application->priv->icon, cairo_surface_destroy); ++ g_clear_pointer (&application->priv->mini_icon, cairo_surface_destroy); + + _wnck_icon_cache_free (application->priv->icon_cache); + application->priv->icon_cache = NULL; +@@ -336,14 +331,20 @@ get_icons (WnckApplication *app) + { + app->priv->need_emit_icon_changed = TRUE; + +- if (app->priv->icon) +- g_object_unref (G_OBJECT (app->priv->icon)); ++ g_clear_pointer (&app->priv->icon, cairo_surface_destroy); ++ g_clear_pointer (&app->priv->mini_icon, cairo_surface_destroy); + +- if (app->priv->mini_icon) +- g_object_unref (G_OBJECT (app->priv->mini_icon)); ++ if (icon) ++ { ++ app->priv->icon = gdk_cairo_surface_create_from_pixbuf (icon, 0, NULL); ++ g_clear_object (&icon); ++ } + +- app->priv->icon = icon; +- app->priv->mini_icon = mini_icon; ++ if (mini_icon) ++ { ++ app->priv->mini_icon = gdk_cairo_surface_create_from_pixbuf (mini_icon, 0, NULL); ++ g_clear_object (&mini_icon); ++ } + } + + /* FIXME we should really fall back to using the icon +@@ -404,12 +405,39 @@ find_icon_window (WnckApplication *app) + GdkPixbuf* + wnck_application_get_icon (WnckApplication *app) + { ++ static const cairo_user_data_key_t app_icon_pixbuf_key; ++ + g_return_val_if_fail (WNCK_IS_APPLICATION (app), NULL); + + _wnck_application_load_icons (app); + + if (app->priv->icon) +- return app->priv->icon; ++ { ++ GdkPixbuf *pixbuf; ++ ++ pixbuf = cairo_surface_get_user_data (app->priv->icon, &app_icon_pixbuf_key); ++ ++ if (pixbuf == NULL) ++ { ++ int scaling_factor; ++ ++ pixbuf = gdk_pixbuf_get_from_surface (app->priv->icon, ++ 0, ++ 0, ++ cairo_image_surface_get_width (app->priv->icon), ++ cairo_image_surface_get_height (app->priv->icon)); ++ ++ scaling_factor = _wnck_get_window_scaling_factor (); ++ pixbuf = gdk_pixbuf_scale_simple (pixbuf, ++ gdk_pixbuf_get_width (pixbuf) / scaling_factor, ++ gdk_pixbuf_get_height (pixbuf) / scaling_factor, ++ GDK_INTERP_BILINEAR); ++ ++ cairo_surface_set_user_data (app->priv->icon, &app_icon_pixbuf_key, pixbuf, g_object_unref); ++ } ++ ++ return pixbuf; ++ } + else + { + WnckWindow *w = find_icon_window (app); +@@ -435,12 +463,39 @@ wnck_application_get_icon (WnckApplication *app) + GdkPixbuf* + wnck_application_get_mini_icon (WnckApplication *app) + { ++ static const cairo_user_data_key_t app_mini_icon_pixbuf_key; ++ + g_return_val_if_fail (WNCK_IS_APPLICATION (app), NULL); + + _wnck_application_load_icons (app); + + if (app->priv->mini_icon) +- return app->priv->mini_icon; ++ { ++ GdkPixbuf *pixbuf; ++ ++ pixbuf = cairo_surface_get_user_data (app->priv->mini_icon, &app_mini_icon_pixbuf_key); ++ ++ if (pixbuf == NULL) ++ { ++ int scaling_factor; ++ ++ pixbuf = gdk_pixbuf_get_from_surface (app->priv->mini_icon, ++ 0, ++ 0, ++ cairo_image_surface_get_width (app->priv->mini_icon), ++ cairo_image_surface_get_height (app->priv->mini_icon)); ++ ++ scaling_factor = _wnck_get_window_scaling_factor (); ++ pixbuf = gdk_pixbuf_scale_simple (pixbuf, ++ gdk_pixbuf_get_width (pixbuf) / scaling_factor, ++ gdk_pixbuf_get_height (pixbuf) / scaling_factor, ++ GDK_INTERP_BILINEAR); ++ ++ cairo_surface_set_user_data (app->priv->mini_icon, &app_mini_icon_pixbuf_key, pixbuf, g_object_unref); ++ } ++ ++ return pixbuf; ++ } + else + { + WnckWindow *w = find_icon_window (app); +@@ -451,6 +506,68 @@ wnck_application_get_mini_icon (WnckApplication *app) + } + } + ++/** ++ * wnck_application_get_icon_surface: ++ * @app: a #WnckApplication. ++ * ++ * Gets the icon-surface to be used for @app. If no icon-surfaceis set for @app, ++ * a suboptimal heuristic is used to find an appropriate icon. If no icon-surface ++ * was found, a fallback icon-surface is used. ++ * ++ * Return value: (transfer full): a reference to the icon-surface for @app. The ++ * caller should unreference the cairo_surface_t once done ++ * with it. ++ **/ ++cairo_surface_t* ++wnck_application_get_icon_surface (WnckApplication *app) ++{ ++ g_return_val_if_fail (WNCK_IS_APPLICATION (app), NULL); ++ ++ _wnck_application_load_icons (app); ++ ++ if (app->priv->icon) ++ return cairo_surface_reference (app->priv->icon); ++ else ++ { ++ WnckWindow *w = find_icon_window (app); ++ if (w) ++ return wnck_window_get_icon_surface (w); ++ else ++ return NULL; ++ } ++} ++ ++/** ++ * wnck_application_get_mini_icon_surface: ++ * @app: a #WnckApplication. ++ * ++ * Gets the mini-icon-surface to be used for @app. If no mini-icon-surfaceis set ++ * for @app, a suboptimal heuristic is used to find an appropriate icon. If no ++ * mini-icon-surface was found, a fallback mini-icon-surface is used. ++ * ++ * Return value: (transfer full): a reference to the mini-icon-surface for @app. ++ * The caller should unreference the cairo_surface_t once ++ * done with it. ++ **/ ++cairo_surface_t* ++wnck_application_get_mini_icon_surface (WnckApplication *app) ++{ ++ g_return_val_if_fail (WNCK_IS_APPLICATION (app), NULL); ++ ++ _wnck_application_load_icons (app); ++ ++ if (app->priv->mini_icon) ++ return cairo_surface_reference (app->priv->mini_icon); ++ else ++ { ++ WnckWindow *w = find_icon_window (app); ++ if (w) ++ return wnck_window_get_mini_icon_surface (w); ++ else ++ return NULL; ++ } ++} ++ + /** + * wnck_application_get_icon_is_fallback: + * @app: a #WnckApplication +diff --git a/libwnck/application.h b/libwnck/application.h +index 40fe4c6..f3ea970 100644 +--- a/libwnck/application.h ++++ b/libwnck/application.h +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + + G_BEGIN_DECLS + +@@ -92,6 +93,8 @@ const char* wnck_application_get_icon_name (WnckApplication *app); + int wnck_application_get_pid (WnckApplication *app); + GdkPixbuf* wnck_application_get_icon (WnckApplication *app); + 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 46d1f24..acdb062 100644 +--- a/libwnck/class-group.c ++++ b/libwnck/class-group.c +@@ -59,8 +59,8 @@ struct _WnckClassGroupPrivate { + GHashTable *window_icon_handlers; + GHashTable *window_name_handlers; + +- GdkPixbuf *icon; +- GdkPixbuf *mini_icon; ++ cairo_surface_t *icon; ++ cairo_surface_t *mini_icon; + }; + + G_DEFINE_TYPE_WITH_PRIVATE (WnckClassGroup, wnck_class_group, G_TYPE_OBJECT); +@@ -171,17 +171,8 @@ wnck_class_group_finalize (GObject *object) + class_group->priv->window_name_handlers = NULL; + } + +- if (class_group->priv->icon) +- { +- g_object_unref (class_group->priv->icon); +- class_group->priv->icon = NULL; +- } +- +- if (class_group->priv->mini_icon) +- { +- g_object_unref (class_group->priv->mini_icon); +- class_group->priv->mini_icon = NULL; +- } ++ g_clear_pointer (&class_group->priv->icon, cairo_surface_destroy); ++ g_clear_pointer (&class_group->priv->mini_icon, cairo_surface_destroy); + + G_OBJECT_CLASS (wnck_class_group_parent_class)->finalize (object); + } +@@ -370,7 +361,8 @@ set_name (WnckClassGroup *class_group) + + /* Walks the list of applications, trying to get an icon from them */ + static void +-get_icons_from_applications (WnckClassGroup *class_group, GdkPixbuf **icon, GdkPixbuf **mini_icon) ++get_icons_from_applications (WnckClassGroup *class_group, ++ cairo_surface_t **icon, cairo_surface_t **mini_icon) + { + GList *l; + +@@ -386,15 +378,15 @@ get_icons_from_applications (WnckClassGroup *class_group, GdkPixbuf **icon, GdkP + app = wnck_window_get_application (window); + if (app) + { +- *icon = wnck_application_get_icon (app); +- *mini_icon = wnck_application_get_mini_icon (app); ++ *icon = wnck_application_get_icon_surface (app); ++ *mini_icon = wnck_application_get_mini_icon_surface (app); + + if (*icon && *mini_icon) + return; + else + { +- *icon = NULL; +- *mini_icon = NULL; ++ g_clear_pointer (icon, cairo_surface_destroy); ++ g_clear_pointer (mini_icon, cairo_surface_destroy); + } + } + } +@@ -402,7 +394,8 @@ get_icons_from_applications (WnckClassGroup *class_group, GdkPixbuf **icon, GdkP + + /* Walks the list of windows, trying to get an icon from them */ + static void +-get_icons_from_windows (WnckClassGroup *class_group, GdkPixbuf **icon, GdkPixbuf **mini_icon) ++get_icons_from_windows (WnckClassGroup *class_group, ++ cairo_surface_t **icon, cairo_surface_t **mini_icon) + { + GList *l; + +@@ -415,15 +408,15 @@ get_icons_from_windows (WnckClassGroup *class_group, GdkPixbuf **icon, GdkPixbuf + + window = WNCK_WINDOW (l->data); + +- *icon = wnck_window_get_icon (window); +- *mini_icon = wnck_window_get_mini_icon (window); ++ *icon = wnck_window_get_icon_surface (window); ++ *mini_icon = wnck_window_get_mini_icon_surface (window); + + if (*icon && *mini_icon) + return; + else + { +- *icon = NULL; +- *mini_icon = NULL; ++ g_clear_pointer (icon, cairo_surface_destroy); ++ g_clear_pointer (mini_icon, cairo_surface_destroy); + } + } + } +@@ -434,7 +427,7 @@ get_icons_from_windows (WnckClassGroup *class_group, GdkPixbuf **icon, GdkPixbuf + static void + set_icon (WnckClassGroup *class_group) + { +- GdkPixbuf *icon, *mini_icon; ++ cairo_surface_t *icon, *mini_icon; + gboolean icons_reffed = FALSE; + + get_icons_from_applications (class_group, &icon, &mini_icon); +@@ -445,31 +438,41 @@ set_icon (WnckClassGroup *class_group) + if (!icon || !mini_icon) + { + WnckHandle *handle; ++ GdkPixbuf *icon_pixbuf, *mini_icon_pixbuf; + + handle = wnck_screen_get_handle (class_group->priv->screen); + +- _wnck_get_fallback_icons (&icon, ++ _wnck_get_fallback_icons (&icon_pixbuf, + _wnck_handle_get_default_icon_size (handle), +- &mini_icon, ++ &mini_icon_pixbuf, + _wnck_handle_get_default_mini_icon_size (handle)); ++ 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; + } + + g_assert (icon && mini_icon); + +- if (class_group->priv->icon) +- g_object_unref (class_group->priv->icon); +- +- if (class_group->priv->mini_icon) +- g_object_unref (class_group->priv->mini_icon); ++ g_clear_pointer (&class_group->priv->icon, cairo_surface_destroy); ++ g_clear_pointer (&class_group->priv->mini_icon, cairo_surface_destroy); + + class_group->priv->icon = icon; + class_group->priv->mini_icon = mini_icon; + + if (!icons_reffed) + { +- g_object_ref (class_group->priv->icon); +- g_object_ref (class_group->priv->mini_icon); ++ cairo_surface_reference (class_group->priv->icon); ++ cairo_surface_reference (class_group->priv->mini_icon); + } + + g_signal_emit (G_OBJECT (class_group), signals[ICON_CHANGED], 0); +@@ -702,9 +705,39 @@ wnck_class_group_get_name (WnckClassGroup *class_group) + GdkPixbuf * + wnck_class_group_get_icon (WnckClassGroup *class_group) + { ++ static const cairo_user_data_key_t class_group_icon_pixbuf_key; ++ + g_return_val_if_fail (class_group != NULL, NULL); + +- return class_group->priv->icon; ++ if (class_group->priv->icon) ++ { ++ GdkPixbuf *pixbuf; ++ ++ pixbuf = cairo_surface_get_user_data (class_group->priv->icon, &class_group_icon_pixbuf_key); ++ ++ if (pixbuf == NULL) ++ { ++ int scaling_factor; ++ ++ pixbuf = gdk_pixbuf_get_from_surface (class_group->priv->icon, ++ 0, ++ 0, ++ cairo_image_surface_get_width (class_group->priv->icon), ++ cairo_image_surface_get_height (class_group->priv->icon)); ++ ++ scaling_factor = _wnck_get_window_scaling_factor (); ++ pixbuf = gdk_pixbuf_scale_simple (pixbuf, ++ gdk_pixbuf_get_width (pixbuf) / scaling_factor, ++ gdk_pixbuf_get_height (pixbuf) / scaling_factor, ++ GDK_INTERP_BILINEAR); ++ ++ cairo_surface_set_user_data (class_group->priv->icon, &class_group_icon_pixbuf_key, pixbuf, g_object_unref); ++ } ++ ++ return pixbuf; ++ } ++ ++ return NULL; + } + + /** +@@ -723,8 +756,76 @@ wnck_class_group_get_icon (WnckClassGroup *class_group) + **/ + GdkPixbuf * + wnck_class_group_get_mini_icon (WnckClassGroup *class_group) ++{ ++ static const cairo_user_data_key_t class_group_mini_icon_pixbuf_key; ++ ++ g_return_val_if_fail (class_group != NULL, NULL); ++ ++ if (class_group->priv->mini_icon) ++ { ++ GdkPixbuf *pixbuf; ++ ++ pixbuf = cairo_surface_get_user_data (class_group->priv->mini_icon, &class_group_mini_icon_pixbuf_key); ++ ++ if (pixbuf == NULL) ++ { ++ int scaling_factor; ++ ++ pixbuf = gdk_pixbuf_get_from_surface (class_group->priv->mini_icon, ++ 0, ++ 0, ++ cairo_image_surface_get_width (class_group->priv->mini_icon), ++ cairo_image_surface_get_height (class_group->priv->mini_icon)); ++ ++ scaling_factor = _wnck_get_window_scaling_factor (); ++ pixbuf = gdk_pixbuf_scale_simple (pixbuf, ++ gdk_pixbuf_get_width (pixbuf) / scaling_factor, ++ gdk_pixbuf_get_height (pixbuf) / scaling_factor, ++ GDK_INTERP_BILINEAR); ++ ++ cairo_surface_set_user_data (class_group->priv->mini_icon, &class_group_mini_icon_pixbuf_key, pixbuf, g_object_unref); ++ } ++ ++ return pixbuf; ++ } ++ ++ return NULL; ++} ++ ++/** ++ * wnck_class_group_get_icon_surface: ++ * @class_group: a #WnckClassGroup. ++ * ++ * Gets the icon-surface to be used for @class_group. Since there is no way to ++ * properly find the icon-surface, the same suboptimal heuristic as the one for ++ * wnck_class_group_get_icon() is used to find it. ++ * ++ * Return value: (transfer full): the icon-surface for @class_group. The caller should ++ * unreference the returned cairo_surface_t once done with it. ++ **/ ++cairo_surface_t * ++wnck_class_group_get_icon_surface (WnckClassGroup *class_group) ++{ ++ g_return_val_if_fail (class_group != NULL, NULL); ++ ++ return cairo_surface_reference (class_group->priv->icon); ++} ++ ++/** ++ * wnck_class_group_get_mini_icon_surface: ++ * @class_group: a #WnckClassGroup. ++ * ++ * Gets the mini-icon-surface to be used for @class_group. Since there is no way to ++ * properly find the mini-icon-surface, the same suboptimal heuristic as the one for ++ * wnck_class_group_get_icon() is used to find it. ++ * ++ * Return value: (transfer full): the mini-icon-surface for @class_group. The caller should ++ * unreference the returned cairo_surface_t once done with it. ++ **/ ++cairo_surface_t * ++wnck_class_group_get_mini_icon_surface (WnckClassGroup *class_group) + { + g_return_val_if_fail (class_group != NULL, NULL); + +- return class_group->priv->mini_icon; ++ return cairo_surface_reference (class_group->priv->mini_icon); + } +diff --git a/libwnck/class-group.h b/libwnck/class-group.h +index 581cd22..122e0ed 100644 +--- a/libwnck/class-group.h ++++ b/libwnck/class-group.h +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + G_BEGIN_DECLS + +@@ -82,6 +83,8 @@ const char * wnck_class_group_get_name (WnckClassGroup *class_group); + + GdkPixbuf *wnck_class_group_get_icon (WnckClassGroup *class_group); + 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); + + #ifndef WNCK_DISABLE_DEPRECATED + G_DEPRECATED_FOR(wnck_class_group_get_id) +diff --git a/libwnck/pager.c b/libwnck/pager.c +index 4df766c..9b09928 100644 +--- a/libwnck/pager.c ++++ b/libwnck/pager.c +@@ -984,8 +984,9 @@ draw_window (cairo_t *cr, + gboolean translucent) + { + GtkStyleContext *context; +- GdkPixbuf *icon; ++ cairo_surface_t *icon; + int icon_x, icon_y, icon_w, icon_h; ++ int scaling_factor; + gboolean is_active; + GdkRGBA fg; + gdouble translucency; +@@ -1015,14 +1016,15 @@ draw_window (cairo_t *cr, + cairo_pop_group_to_source (cr); + cairo_paint_with_alpha (cr, translucency); + +- icon = wnck_window_get_icon (win); ++ icon = wnck_window_get_icon_surface (win); + + icon_w = icon_h = 0; ++ scaling_factor = gtk_widget_get_scale_factor (widget); + + if (icon) + { +- icon_w = gdk_pixbuf_get_width (icon); +- icon_h = gdk_pixbuf_get_height (icon); ++ icon_w = cairo_image_surface_get_width (icon) / scaling_factor; ++ icon_h = cairo_image_surface_get_height (icon) / scaling_factor; + + /* If the icon is too big, fall back to mini icon. + * We don't arbitrarily scale the icon, because it's +@@ -1031,11 +1033,12 @@ draw_window (cairo_t *cr, + if (icon_w > (winrect->width - 2) || + icon_h > (winrect->height - 2)) + { +- icon = wnck_window_get_mini_icon (win); ++ cairo_surface_destroy (icon); ++ icon = wnck_window_get_mini_icon_surface (win); + if (icon) + { +- icon_w = gdk_pixbuf_get_width (icon); +- icon_h = gdk_pixbuf_get_height (icon); ++ icon_w = cairo_image_surface_get_width (icon) / scaling_factor; ++ icon_h = cairo_image_surface_get_height (icon) / scaling_factor; + + /* Give up. */ + if (icon_w > (winrect->width - 2) || +@@ -1051,7 +1054,7 @@ draw_window (cairo_t *cr, + icon_y = winrect->y + (winrect->height - icon_h) / 2; + + cairo_push_group (cr); +- gtk_render_icon (context, cr, icon, icon_x, icon_y); ++ gtk_render_icon_surface (context, cr, icon, icon_x, icon_y); + cairo_pop_group_to_source (cr); + cairo_paint_with_alpha (cr, translucency); + } +@@ -1072,6 +1075,7 @@ draw_window (cairo_t *cr, + cairo_stroke (cr); + + gtk_style_context_restore (context); ++ cairo_surface_destroy (icon); + } + + static WnckWindow * +diff --git a/libwnck/selector.c b/libwnck/selector.c +index 26fb5ba..8eac246 100644 +--- a/libwnck/selector.c ++++ b/libwnck/selector.c +@@ -135,103 +135,96 @@ wnck_selector_get_screen (WnckSelector *selector) + gdk_x11_screen_get_screen_number (screen)); + } + +-static GdkPixbuf * ++static cairo_surface_t * + wnck_selector_get_default_window_icon (void) + { +- static GdkPixbuf *retval = NULL; ++ static cairo_surface_t *retval = NULL; ++ GdkPixbuf *pixbuf; + + if (retval) + return retval; + +- retval = gdk_pixbuf_new_from_resource ("/org/gnome/libwnck/default_icon.png", NULL); ++ pixbuf = gdk_pixbuf_new_from_resource ("/org/gnome/libwnck/default_icon.png", NULL); + +- g_assert (retval); ++ g_assert (pixbuf); ++ ++ retval = gdk_cairo_surface_create_from_pixbuf (pixbuf, 0, NULL); ++ ++ g_object_unref (pixbuf); + + return retval; + } + +-static GdkPixbuf * +-wnck_selector_dimm_icon (GdkPixbuf *pixbuf) ++static void ++wnck_selector_dimm_icon (cairo_t *cr, cairo_surface_t *surface) + { +- int x, y, pixel_stride, row_stride; +- guchar *row, *pixels; +- int w, h; +- GdkPixbuf *dimmed; ++ cairo_surface_t *temp; ++ cairo_t *temp_cr; + +- w = gdk_pixbuf_get_width (pixbuf); +- h = gdk_pixbuf_get_height (pixbuf); ++ g_assert (surface != NULL); ++ g_assert (cairo_surface_get_content (surface) != CAIRO_CONTENT_COLOR); + +- if (gdk_pixbuf_get_has_alpha (pixbuf)) +- dimmed = gdk_pixbuf_copy (pixbuf); +- else +- dimmed = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0); ++ temp = cairo_surface_create_similar (surface, ++ cairo_surface_get_content (surface), ++ cairo_image_surface_get_width (surface), ++ cairo_image_surface_get_height (surface)); + +- pixel_stride = 4; ++ temp_cr = cairo_create (temp); + +- row = gdk_pixbuf_get_pixels (dimmed); +- row_stride = gdk_pixbuf_get_rowstride (dimmed); ++ cairo_set_source_surface (temp_cr, surface, 0, 0); ++ cairo_paint_with_alpha (temp_cr, 0.5); + +- for (y = 0; y < h; y++) +- { +- pixels = row; +- for (x = 0; x < w; x++) +- { +- pixels[3] /= 2; +- pixels += pixel_stride; +- } +- row += row_stride; +- } ++ cairo_set_operator (cr, CAIRO_OPERATOR_IN); ++ cairo_set_source_surface (cr, temp, 0, 0); ++ cairo_paint (cr); + +- return dimmed; ++ cairo_destroy (temp_cr); ++ cairo_surface_destroy (temp); + } + + void + _wnck_selector_set_window_icon (GtkWidget *image, + WnckWindow *window) + { +- GdkPixbuf *pixbuf, *freeme, *freeme2; +- int width, height; ++ cairo_surface_t *orig, *surface; ++ cairo_t *cr; ++ int scaling_factor; + int icon_size = -1; + +- pixbuf = NULL; +- freeme = NULL; +- freeme2 = NULL; ++ orig = NULL; ++ surface = NULL; + + if (window) +- pixbuf = wnck_window_get_mini_icon (window); ++ orig = wnck_window_get_mini_icon_surface (window); + +- if (!pixbuf) +- pixbuf = wnck_selector_get_default_window_icon (); ++ if (!orig) ++ orig = wnck_selector_get_default_window_icon (); + + if (icon_size == -1) + gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &icon_size); + +- width = gdk_pixbuf_get_width (pixbuf); +- height = gdk_pixbuf_get_height (pixbuf); ++ surface = cairo_surface_create_similar_image (orig, ++ cairo_image_surface_get_format (orig), ++ cairo_image_surface_get_width (orig), ++ cairo_image_surface_get_height (orig)); + +- if (icon_size != -1 && (width > icon_size || height > icon_size)) +- { +- double scale; ++ scaling_factor = _wnck_get_window_scaling_factor (); ++ cairo_surface_set_device_scale (surface, (double)scaling_factor, (double)scaling_factor); + +- scale = ((double) icon_size) / MAX (width, height); ++ cr = cairo_create (surface); + +- pixbuf = gdk_pixbuf_scale_simple (pixbuf, width * scale, +- height * scale, GDK_INTERP_BILINEAR); +- freeme = pixbuf; +- } ++ cairo_set_source_surface (cr, orig, 0, 0); ++ cairo_paint (cr); + + if (window && wnck_window_is_minimized (window)) + { +- pixbuf = wnck_selector_dimm_icon (pixbuf); +- freeme2 = pixbuf; ++ wnck_selector_dimm_icon (cr, surface); + } + +- gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf); ++ gtk_image_set_from_surface (GTK_IMAGE (image), surface); + +- if (freeme) +- g_object_unref (freeme); +- if (freeme2) +- g_object_unref (freeme2); ++ cairo_destroy (cr); ++ cairo_surface_destroy (surface); + } + + static void +diff --git a/libwnck/tasklist.c b/libwnck/tasklist.c +index ccc7427..b7e783b 100644 +--- a/libwnck/tasklist.c ++++ b/libwnck/tasklist.c +@@ -292,11 +292,11 @@ static WnckTask *wnck_task_new_from_startup_sequence (WnckTasklist *tasklis + #endif + static gboolean wnck_task_get_needs_attention (WnckTask *task); + ++static cairo_surface_t *wnck_task_get_icon (WnckTask *task); + + static char *wnck_task_get_text (WnckTask *task, + gboolean icon_text, + gboolean include_state); +-static GdkPixbuf *wnck_task_get_icon (WnckTask *task); + static gint wnck_task_compare_alphabetically (gconstpointer a, + gconstpointer b); + static gint wnck_task_compare (gconstpointer a, +@@ -685,10 +685,10 @@ wnck_button_new (WnckTasklist *tasklist) + } + + static void +-wnck_button_set_image_from_pixbuf (WnckButton *self, +- GdkPixbuf *pixbuf) ++wnck_button_set_image_from_surface (WnckButton *self, ++ cairo_surface_t *surface) + { +- gtk_image_set_from_pixbuf (GTK_IMAGE (self->image), pixbuf); ++ gtk_image_set_from_surface (GTK_IMAGE (self->image), surface); + } + + static void +@@ -3598,7 +3598,7 @@ wnck_task_popup_menu (WnckTask *task, + GtkWidget *menu; + WnckTask *win_task; + char *text; +- GdkPixbuf *pixbuf; ++ cairo_surface_t *surface; + GtkWidget *menu_item; + GList *l, *list; + +@@ -3645,15 +3645,15 @@ wnck_task_popup_menu (WnckTask *task, + g_free (text); + } + +- pixbuf = wnck_task_get_icon (win_task); +- if (pixbuf) ++ surface = wnck_task_get_icon (win_task); ++ if (surface) + { + WnckImageMenuItem *item; + + item = WNCK_IMAGE_MENU_ITEM (menu_item); + +- wnck_image_menu_item_set_image_from_icon_pixbuf (item, pixbuf); +- g_object_unref (pixbuf); ++ wnck_image_menu_item_set_image_from_icon_surface (item, surface); ++ cairo_surface_destroy (surface); + } + + gtk_widget_show (menu_item); +@@ -3839,102 +3839,76 @@ wnck_task_get_text (WnckTask *task, + } + + static void +-wnck_dimm_icon (GdkPixbuf *pixbuf) ++wnck_dimm_icon (cairo_t *cr, cairo_surface_t *surface) + { +- int x, y, pixel_stride, row_stride; +- guchar *row, *pixels; +- int w, h; ++ cairo_surface_t *temp; ++ cairo_t *temp_cr; + +- g_assert (pixbuf != NULL); ++ g_assert (surface != NULL); ++ g_assert (cairo_surface_get_content (surface) != CAIRO_CONTENT_COLOR); + +- w = gdk_pixbuf_get_width (pixbuf); +- h = gdk_pixbuf_get_height (pixbuf); ++ temp = cairo_surface_create_similar (surface, ++ cairo_surface_get_content (surface), ++ cairo_image_surface_get_width (surface), ++ cairo_image_surface_get_height (surface)); + +- g_assert (gdk_pixbuf_get_has_alpha (pixbuf)); ++ temp_cr = cairo_create (temp); + +- pixel_stride = 4; ++ cairo_set_source_surface (temp_cr, surface, 0, 0); ++ cairo_paint_with_alpha (temp_cr, 0.5); + +- row = gdk_pixbuf_get_pixels (pixbuf); +- row_stride = gdk_pixbuf_get_rowstride (pixbuf); ++ cairo_set_operator (cr, CAIRO_OPERATOR_IN); ++ cairo_set_source_surface (cr, temp, 0, 0); ++ cairo_paint (cr); + +- for (y = 0; y < h; y++) +- { +- pixels = row; +- +- for (x = 0; x < w; x++) +- { +- pixels[3] /= 2; +- +- pixels += pixel_stride; +- } +- +- row += row_stride; +- } ++ cairo_destroy (temp_cr); ++ cairo_surface_destroy (temp); + } + +-static GdkPixbuf * +-wnck_task_scale_icon (gsize mini_icon_size, +- GdkPixbuf *orig, +- gboolean minimized) ++static cairo_surface_t * ++wnck_task_scale_icon (cairo_surface_t *orig, gboolean minimized) + { +- int w, h; +- GdkPixbuf *pixbuf; ++ int scaling_factor; ++ cairo_surface_t *surface; ++ cairo_t *cr; + + if (!orig) + return NULL; + +- w = gdk_pixbuf_get_width (orig); +- h = gdk_pixbuf_get_height (orig); ++ surface = cairo_surface_create_similar_image (orig, ++ cairo_image_surface_get_format (orig), ++ cairo_image_surface_get_width (orig), ++ cairo_image_surface_get_height (orig)); + +- if (h != (int) mini_icon_size || +- !gdk_pixbuf_get_has_alpha (orig)) +- { +- double scale; +- +- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, +- TRUE, +- 8, +- mini_icon_size * w / (double) h, +- mini_icon_size); +- +- scale = mini_icon_size / (double) gdk_pixbuf_get_height (orig); +- +- gdk_pixbuf_scale (orig, +- pixbuf, +- 0, 0, +- gdk_pixbuf_get_width (pixbuf), +- gdk_pixbuf_get_height (pixbuf), +- 0, 0, +- scale, scale, +- GDK_INTERP_HYPER); +- } +- else +- pixbuf = orig; ++ scaling_factor = _wnck_get_window_scaling_factor (); ++ cairo_surface_set_device_scale (surface, (double)scaling_factor, (double)scaling_factor); ++ ++ cr = cairo_create (surface); ++ ++ cairo_set_source_surface (cr, orig, 0, 0); ++ cairo_paint (cr); + + if (minimized) + { +- if (orig == pixbuf) +- pixbuf = gdk_pixbuf_copy (orig); +- +- wnck_dimm_icon (pixbuf); ++ wnck_dimm_icon (cr, surface); + } + +- if (orig == pixbuf) +- g_object_ref (pixbuf); ++ cairo_destroy (cr); + +- return pixbuf; ++ return surface; + } + + +-static GdkPixbuf * ++static cairo_surface_t * + wnck_task_get_icon (WnckTask *task) + { + WnckWindowState state; +- GdkPixbuf *pixbuf; ++ cairo_surface_t *surface; ++ cairo_surface_t *mini_icon; + WnckHandle *handle; + gsize mini_icon_size; + +- pixbuf = NULL; ++ surface = NULL; + + handle = task->tasklist->priv->handle; + mini_icon_size = _wnck_handle_get_default_mini_icon_size (handle); +@@ -3942,17 +3916,19 @@ wnck_task_get_icon (WnckTask *task) + switch (task->type) + { + case WNCK_TASK_CLASS_GROUP: +- pixbuf = wnck_task_scale_icon (mini_icon_size, +- wnck_class_group_get_mini_icon (task->class_group), +- FALSE); ++ mini_icon = wnck_class_group_get_mini_icon_surface (task->class_group); ++ surface = wnck_task_scale_icon (mini_icon, FALSE); ++ ++ cairo_surface_destroy (mini_icon); + break; + + case WNCK_TASK_WINDOW: + state = wnck_window_get_state (task->window); + +- pixbuf = wnck_task_scale_icon (mini_icon_size, +- wnck_window_get_mini_icon (task->window), +- state & WNCK_WINDOW_STATE_MINIMIZED); ++ mini_icon = wnck_window_get_mini_icon_surface (task->window); ++ surface = wnck_task_scale_icon (mini_icon, state & WNCK_WINDOW_STATE_MINIMIZED); ++ ++ cairo_surface_destroy (mini_icon); + break; + + case WNCK_TASK_STARTUP_SEQUENCE: +@@ -3973,16 +3949,28 @@ wnck_task_get_icon (WnckTask *task) + + if (loaded != NULL) + { +- pixbuf = wnck_task_scale_icon (mini_icon_size, loaded, FALSE); ++ cairo_surface_t *temp; ++ ++ temp = gdk_cairo_surface_create_from_pixbuf (loaded, 0, NULL); ++ surface = wnck_task_scale_icon (temp, FALSE); ++ ++ cairo_surface_destroy (temp); + g_object_unref (G_OBJECT (loaded)); + } + } + } + +- if (pixbuf == NULL) ++ 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); ++ } + } + #endif + break; +@@ -3991,7 +3979,7 @@ wnck_task_get_icon (WnckTask *task) + break; + } + +- return pixbuf; ++ return surface; + } + + static gboolean +@@ -4040,12 +4028,13 @@ wnck_task_get_needs_attention (WnckTask *task) + static void + wnck_task_update_visible_state (WnckTask *task) + { +- GdkPixbuf *pixbuf; ++ cairo_surface_t *surface; + char *text; + +- pixbuf = wnck_task_get_icon (task); +- wnck_button_set_image_from_pixbuf (WNCK_BUTTON (task->button), pixbuf); +- g_clear_object (&pixbuf); ++ surface = wnck_task_get_icon (task); ++ wnck_button_set_image_from_surface (WNCK_BUTTON (task->button), surface); ++ if (surface) ++ cairo_surface_destroy (surface); + + text = wnck_task_get_text (task, TRUE, TRUE); + if (text != NULL) +@@ -4516,7 +4505,7 @@ wnck_task_draw (GtkWidget *widget, + static void + wnck_task_create_widgets (WnckTask *task, GtkReliefStyle relief) + { +- GdkPixbuf *pixbuf; ++ cairo_surface_t *surface; + char *text; + static const GtkTargetEntry targets[] = { + { (gchar *) "application/x-wnck-window-id", 0, 0 } +@@ -4543,9 +4532,9 @@ wnck_task_create_widgets (WnckTask *task, GtkReliefStyle relief) + gtk_drag_dest_set (GTK_WIDGET (task->button), 0, + NULL, 0, GDK_ACTION_DEFAULT); + +- pixbuf = wnck_task_get_icon (task); +- wnck_button_set_image_from_pixbuf (WNCK_BUTTON (task->button), pixbuf); +- g_clear_object (&pixbuf); ++ surface = wnck_task_get_icon (task); ++ wnck_button_set_image_from_surface (WNCK_BUTTON (task->button), surface); ++ cairo_surface_destroy (surface); + + text = wnck_task_get_text (task, TRUE, TRUE); + wnck_button_set_text (WNCK_BUTTON (task->button), text); +diff --git a/libwnck/util.c b/libwnck/util.c +index a58a99e..d8942b4 100644 +--- a/libwnck/util.c ++++ b/libwnck/util.c +@@ -200,6 +200,12 @@ wnck_set_default_icon_size (gsize size) + wnck_handle_set_default_icon_size (_wnck_get_handle(), size); + } + ++gsize ++_wnck_get_default_icon_size (void) ++{ ++ return _wnck_handle_get_default_icon_size (_wnck_get_handle ()) * _wnck_get_window_scaling_factor (); ++} ++ + /** + * wnck_set_default_mini_icon_size: + * @size: the default size for windows and application mini icons. +@@ -215,6 +221,12 @@ wnck_set_default_mini_icon_size (gsize size) + wnck_handle_set_default_mini_icon_size (_wnck_get_handle (), size); + } + ++gsize ++_wnck_get_default_mini_icon_size (void) ++{ ++ return _wnck_handle_get_default_mini_icon_size (_wnck_get_handle ()) * _wnck_get_window_scaling_factor (); ++} ++ + /** + * _make_gtk_label_bold: + * @label: The label. +diff --git a/libwnck/window.c b/libwnck/window.c +index 6e23d01..52504f6 100644 +--- a/libwnck/window.c ++++ b/libwnck/window.c +@@ -88,8 +88,8 @@ struct _WnckWindowPrivate + + WnckWindowType wintype; + +- GdkPixbuf *icon; +- GdkPixbuf *mini_icon; ++ cairo_surface_t *icon; ++ cairo_surface_t *mini_icon; + + WnckIconCache *icon_cache; + +@@ -412,13 +412,8 @@ wnck_window_finalize (GObject *object) + g_free (window->priv->session_id_utf8); + window->priv->session_id_utf8 = NULL; + +- if (window->priv->icon) +- g_object_unref (G_OBJECT (window->priv->icon)); +- window->priv->icon = NULL; +- +- if (window->priv->mini_icon) +- g_object_unref (G_OBJECT (window->priv->mini_icon)); +- window->priv->mini_icon = NULL; ++ g_clear_pointer (&window->priv->icon, cairo_surface_destroy); ++ g_clear_pointer (&window->priv->mini_icon, cairo_surface_destroy); + + _wnck_icon_cache_free (window->priv->icon_cache); + window->priv->icon_cache = NULL; +@@ -2140,14 +2135,20 @@ get_icons (WnckWindow *window) + { + window->priv->need_emit_icon_changed = TRUE; + +- if (window->priv->icon) +- g_object_unref (G_OBJECT (window->priv->icon)); ++ g_clear_pointer (&window->priv->icon, cairo_surface_destroy); ++ g_clear_pointer (&window->priv->mini_icon, cairo_surface_destroy); + +- if (window->priv->mini_icon) +- g_object_unref (G_OBJECT (window->priv->mini_icon)); ++ if (icon) ++ { ++ window->priv->icon = gdk_cairo_surface_create_from_pixbuf (icon, 0, NULL); ++ g_clear_object (&icon); ++ } + +- window->priv->icon = icon; +- window->priv->mini_icon = mini_icon; ++ if (mini_icon) ++ { ++ window->priv->mini_icon = gdk_cairo_surface_create_from_pixbuf (mini_icon, 0, NULL); ++ g_clear_object (&mini_icon); ++ } + } + + g_assert ((window->priv->icon && window->priv->mini_icon) || +@@ -2181,11 +2182,41 @@ _wnck_window_load_icons (WnckWindow *window) + GdkPixbuf* + wnck_window_get_icon (WnckWindow *window) + { ++ static const cairo_user_data_key_t window_icon_pixbuf_key; ++ + g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL); + + _wnck_window_load_icons (window); + +- return window->priv->icon; ++ if (window->priv->icon) ++ { ++ GdkPixbuf *pixbuf; ++ ++ pixbuf = cairo_surface_get_user_data (window->priv->icon, &window_icon_pixbuf_key); ++ ++ if (pixbuf == NULL) ++ { ++ int scaling_factor; ++ ++ pixbuf = gdk_pixbuf_get_from_surface (window->priv->icon, ++ 0, ++ 0, ++ cairo_image_surface_get_width (window->priv->icon), ++ cairo_image_surface_get_height (window->priv->icon)); ++ ++ scaling_factor = _wnck_get_window_scaling_factor (); ++ pixbuf = gdk_pixbuf_scale_simple (pixbuf, ++ gdk_pixbuf_get_width (pixbuf) / scaling_factor, ++ gdk_pixbuf_get_height (pixbuf) / scaling_factor, ++ GDK_INTERP_BILINEAR); ++ ++ cairo_surface_set_user_data (window->priv->icon, &window_icon_pixbuf_key, pixbuf, g_object_unref); ++ } ++ ++ return pixbuf; ++ } ++ ++ return NULL; + } + + /** +@@ -2202,12 +2233,86 @@ wnck_window_get_icon (WnckWindow *window) + **/ + GdkPixbuf* + wnck_window_get_mini_icon (WnckWindow *window) ++{ ++ static const cairo_user_data_key_t window_mini_icon_pixbuf_key; ++ ++ g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL); ++ ++ _wnck_window_load_icons (window); ++ ++ if (window->priv->mini_icon) ++ { ++ GdkPixbuf *pixbuf; ++ ++ pixbuf = cairo_surface_get_user_data (window->priv->mini_icon, &window_mini_icon_pixbuf_key); ++ ++ if (pixbuf == NULL) ++ { ++ int scaling_factor; ++ ++ pixbuf = gdk_pixbuf_get_from_surface (window->priv->mini_icon, ++ 0, ++ 0, ++ cairo_image_surface_get_width (window->priv->mini_icon), ++ cairo_image_surface_get_height (window->priv->mini_icon)); ++ ++ scaling_factor = _wnck_get_window_scaling_factor (); ++ pixbuf = gdk_pixbuf_scale_simple (pixbuf, ++ gdk_pixbuf_get_width (pixbuf) / scaling_factor, ++ gdk_pixbuf_get_height (pixbuf) / scaling_factor, ++ GDK_INTERP_BILINEAR); ++ ++ cairo_surface_set_user_data (window->priv->mini_icon, &window_mini_icon_pixbuf_key, pixbuf, g_object_unref); ++ } ++ ++ return pixbuf; ++ } ++ ++ return NULL; ++} ++ ++/** ++ * wnck_window_get_icon_surface: ++ * @window: a #WnckWindow. ++ * ++ * Gets the icon-surface to be used for @window. If no icon-surface was found, a ++ * fallback icon-surface is used. wnck_window_get_icon_is_fallback() can be used ++ * to tell if the icon-surface is the fallback icon-surface. ++ * ++ * Return value: (transfer full): a reference to the icon-surface for @window. ++ * The caller should unreference the returned cairo_surface_t ++ * once done with it. ++ **/ ++cairo_surface_t* ++wnck_window_get_icon_surface (WnckWindow *window) ++{ ++ g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL); ++ ++ _wnck_window_load_icons (window); ++ ++ return cairo_surface_reference (window->priv->icon); ++} ++ ++/** ++ * wnck_window_get_mini_icon_surface: ++ * @window: a #WnckWindow. ++ * ++ * Gets the mini-icon-surface to be used for @window. If no mini-icon-surface ++ * was found, a fallback mini-icon-surface is used. wnck_window_get_icon_is_fallback() ++ * can be used to tell if the mini-icon-surface is the fallback mini-icon-surface. ++ * ++ * Return value: (transfer full): a reference to the mini-icon-surface for @window. ++ * The caller should unreference the returned cairo_surface_t ++ * once done with it. ++ **/ ++cairo_surface_t* ++wnck_window_get_mini_icon_surface (WnckWindow *window) + { + g_return_val_if_fail (WNCK_IS_WINDOW (window), NULL); + + _wnck_window_load_icons (window); + +- return window->priv->mini_icon; ++ return cairo_surface_reference (window->priv->mini_icon); + } + + /** +diff --git a/libwnck/window.h b/libwnck/window.h +index 47c6543..2bec086 100644 +--- a/libwnck/window.h ++++ b/libwnck/window.h +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + + G_BEGIN_DECLS + +@@ -382,6 +383,8 @@ gboolean wnck_window_transient_is_most_recently_activated (WnckWindow *window); + + GdkPixbuf* wnck_window_get_icon (WnckWindow *window); + 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); + + gboolean wnck_window_get_icon_is_fallback (WnckWindow *window); + +diff --git a/libwnck/wnck-image-menu-item-private.h b/libwnck/wnck-image-menu-item-private.h +index e5a3288..ccfb5b2 100644 +--- a/libwnck/wnck-image-menu-item-private.h ++++ b/libwnck/wnck-image-menu-item-private.h +@@ -34,6 +34,9 @@ GtkWidget *wnck_image_menu_item_new_with_label (const gchar *l + void wnck_image_menu_item_set_image_from_icon_pixbuf (WnckImageMenuItem *item, + GdkPixbuf *pixbuf); + ++void wnck_image_menu_item_set_image_from_icon_surface (WnckImageMenuItem *item, ++ cairo_surface_t *surface); ++ + void wnck_image_menu_item_set_image_from_window (WnckImageMenuItem *item, + WnckWindow *window); + +diff --git a/libwnck/wnck-image-menu-item.c b/libwnck/wnck-image-menu-item.c +index 3041ae6..b088d53 100644 +--- a/libwnck/wnck-image-menu-item.c ++++ b/libwnck/wnck-image-menu-item.c +@@ -218,6 +218,14 @@ wnck_image_menu_item_set_image_from_icon_pixbuf (WnckImageMenuItem *item, + gtk_widget_show (item->image); + } + ++void ++wnck_image_menu_item_set_image_from_icon_surface (WnckImageMenuItem *item, ++ cairo_surface_t *surface) ++{ ++ gtk_image_set_from_surface (GTK_IMAGE (item->image), surface); ++ gtk_widget_show (item->image); ++} ++ + void + wnck_image_menu_item_set_image_from_window (WnckImageMenuItem *item, + WnckWindow *window) +-- +2.46.1 + diff --git a/SPECS-EXTENDED/libwnck3/libwnck_0003-xutils-Change-icons-to-being-cairo-surfaces_v43.1.patch b/SPECS-EXTENDED/libwnck3/libwnck_0003-xutils-Change-icons-to-being-cairo-surfaces_v43.1.patch new file mode 100644 index 00000000000..3d484177db3 --- /dev/null +++ b/SPECS-EXTENDED/libwnck3/libwnck_0003-xutils-Change-icons-to-being-cairo-surfaces_v43.1.patch @@ -0,0 +1,797 @@ +From c3c3a3a95ba079fbc7f4bd43cbe6836b9b53a818 Mon Sep 17 00:00:00 2001 +From: Victor Kareh +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 | 16 +- + libwnck/tasklist.c | 9 +- + libwnck/util.c | 4 +- + libwnck/window.c | 22 +-- + libwnck/wnck-icon-cache-private.h | 15 +- + libwnck/wnck-icon-cache.c | 299 +++++++++++++----------------- + libwnck/xutils.c | 42 ++--- + libwnck/xutils.h | 11 +- + 9 files changed, 181 insertions(+), 259 deletions(-) + +diff --git a/libwnck/application.c b/libwnck/application.c +index 77958c4..be1107d 100644 +--- a/libwnck/application.c ++++ b/libwnck/application.c +@@ -309,10 +309,11 @@ static void + get_icons (WnckApplication *app) + { + WnckHandle *handle; +- GdkPixbuf *icon; +- GdkPixbuf *mini_icon; ++ cairo_surface_t *icon; ++ cairo_surface_t *mini_icon; + gsize normal_size; + gsize mini_size; ++ int scaling_factor; + + handle = wnck_screen_get_handle (app->priv->screen); + +@@ -320,6 +321,7 @@ get_icons (WnckApplication *app) + mini_icon = NULL; + normal_size = _wnck_handle_get_default_icon_size (handle); + mini_size = _wnck_handle_get_default_mini_icon_size (handle); ++ scaling_factor = _wnck_get_window_scaling_factor (); + + if (_wnck_read_icons (app->priv->screen, + app->priv->xwindow, +@@ -327,24 +329,16 @@ get_icons (WnckApplication *app) + &icon, + normal_size, + &mini_icon, +- mini_size)) ++ mini_size, ++ scaling_factor)) + { + app->priv->need_emit_icon_changed = TRUE; + + 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 acdb062..7899497 100644 +--- a/libwnck/class-group.c ++++ b/libwnck/class-group.c +@@ -438,25 +438,13 @@ set_icon (WnckClassGroup *class_group) + if (!icon || !mini_icon) + { + WnckHandle *handle; +- GdkPixbuf *icon_pixbuf, *mini_icon_pixbuf; + + handle = wnck_screen_get_handle (class_group->priv->screen); + +- _wnck_get_fallback_icons (&icon_pixbuf, ++ _wnck_get_fallback_icons (&icon, + _wnck_handle_get_default_icon_size (handle), +- &mini_icon_pixbuf, ++ &mini_icon, + _wnck_handle_get_default_mini_icon_size (handle)); +- 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 b7e783b..70bbff3 100644 +--- a/libwnck/tasklist.c ++++ b/libwnck/tasklist.c +@@ -3962,15 +3962,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 d8942b4..5a214e0 100644 +--- a/libwnck/util.c ++++ b/libwnck/util.c +@@ -203,7 +203,7 @@ wnck_set_default_icon_size (gsize size) + gsize + _wnck_get_default_icon_size (void) + { +- return _wnck_handle_get_default_icon_size (_wnck_get_handle ()) * _wnck_get_window_scaling_factor (); ++ return _wnck_handle_get_default_icon_size (_wnck_get_handle ()); + } + + /** +@@ -224,7 +224,7 @@ wnck_set_default_mini_icon_size (gsize size) + gsize + _wnck_get_default_mini_icon_size (void) + { +- return _wnck_handle_get_default_mini_icon_size (_wnck_get_handle ()) * _wnck_get_window_scaling_factor (); ++ return _wnck_handle_get_default_mini_icon_size (_wnck_get_handle ()); + } + + /** +diff --git a/libwnck/window.c b/libwnck/window.c +index 52504f6..094dc5a 100644 +--- a/libwnck/window.c ++++ b/libwnck/window.c +@@ -2113,10 +2113,11 @@ static void + get_icons (WnckWindow *window) + { + WnckHandle *handle; +- GdkPixbuf *icon; +- GdkPixbuf *mini_icon; ++ cairo_surface_t *icon; ++ cairo_surface_t *mini_icon; + gsize normal_size; + gsize mini_size; ++ int scaling_factor; + + handle = wnck_screen_get_handle (window->priv->screen); + +@@ -2124,6 +2125,7 @@ get_icons (WnckWindow *window) + mini_icon = NULL; + normal_size = _wnck_handle_get_default_icon_size (handle); + mini_size = _wnck_handle_get_default_mini_icon_size (handle); ++ scaling_factor = _wnck_get_window_scaling_factor (); + + if (_wnck_read_icons (window->priv->screen, + window->priv->xwindow, +@@ -2131,24 +2133,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 9ff8d15..d9e67e8 100644 +--- a/libwnck/wnck-icon-cache.c ++++ b/libwnck/wnck-icon-cache.c +@@ -44,8 +44,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; +@@ -139,49 +139,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; +@@ -219,7 +235,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; +@@ -233,14 +251,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); + +@@ -248,27 +260,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; + +@@ -324,26 +336,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 +@@ -354,13 +381,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; + +@@ -372,89 +394,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) + { +@@ -528,22 +487,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 */ +@@ -556,6 +510,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); +@@ -566,8 +523,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. +@@ -579,21 +534,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); + +@@ -604,6 +553,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); +@@ -632,7 +584,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 91c2d50..6ce6a1e 100644 +--- a/libwnck/xutils.c ++++ b/libwnck/xutils.c +@@ -1408,7 +1408,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; +@@ -1426,6 +1427,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, +@@ -1482,7 +1486,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; +@@ -1497,36 +1501,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 700832a..18cb8bf 100644 +--- a/libwnck/xutils.h ++++ b/libwnck/xutils.h +@@ -156,10 +156,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, +@@ -192,7 +192,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.46.1 + diff --git a/SPECS-EXTENDED/libwnck3/libwnck_0004-icons-Mark-GdkPixbuf-icons-as-deprecated_v43.1.patch b/SPECS-EXTENDED/libwnck3/libwnck_0004-icons-Mark-GdkPixbuf-icons-as-deprecated_v43.1.patch new file mode 100644 index 00000000000..08240cf81ec --- /dev/null +++ b/SPECS-EXTENDED/libwnck3/libwnck_0004-icons-Mark-GdkPixbuf-icons-as-deprecated_v43.1.patch @@ -0,0 +1,189 @@ +From a0590c5c69ba16c94701c63881e536269ffbe544 Mon Sep 17 00:00:00 2001 +From: Victor Kareh +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 be1107d..a0c8887 100644 +--- a/libwnck/application.c ++++ b/libwnck/application.c +@@ -395,6 +395,8 @@ find_icon_window (WnckApplication *app) + * Return value: (transfer none): the icon for @app. The caller should + * reference the returned GdkPixbuf 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) +@@ -434,10 +436,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; + } + } +@@ -453,6 +457,8 @@ wnck_application_get_icon (WnckApplication *app) + * Return value: (transfer none): the mini-icon for @app. The caller should + * reference the returned GdkPixbuf 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) +@@ -492,10 +498,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 f3ea970..4d9078e 100644 +--- a/libwnck/application.h ++++ b/libwnck/application.h +@@ -91,10 +91,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 7899497..026e995 100644 +--- a/libwnck/class-group.c ++++ b/libwnck/class-group.c +@@ -689,6 +689,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) +@@ -741,6 +743,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 122e0ed..dee0e7c 100644 +--- a/libwnck/class-group.h ++++ b/libwnck/class-group.h +@@ -81,8 +81,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 77085cd..649c2e6 100644 +--- a/libwnck/test-wnck.c ++++ b/libwnck/test-wnck.c +@@ -523,7 +523,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 094dc5a..8723995 100644 +--- a/libwnck/window.c ++++ b/libwnck/window.c +@@ -21,6 +21,8 @@ + * License along with this library; if not, see . + */ + ++#undef WNCK_DISABLE_DEPRECATED ++ + #include + + #include +@@ -2172,6 +2174,8 @@ _wnck_window_load_icons (WnckWindow *window) + * Return value: (transfer none): the icon for @window. The caller should + * reference the returned GdkPixbuf 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) +@@ -2224,6 +2228,8 @@ wnck_window_get_icon (WnckWindow *window) + * Return value: (transfer none): the mini-icon for @window. The caller should + * reference the returned GdkPixbuf 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 2bec086..d7e52f1 100644 +--- a/libwnck/window.h ++++ b/libwnck/window.h +@@ -381,8 +381,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.46.1 + diff --git a/SPECS-EXTENDED/libwnck3/libwnck_0005-tasklist-Add-surface-loader-function_v43.1.patch b/SPECS-EXTENDED/libwnck3/libwnck_0005-tasklist-Add-surface-loader-function_v43.1.patch new file mode 100644 index 00000000000..f62e70ab3ea --- /dev/null +++ b/SPECS-EXTENDED/libwnck3/libwnck_0005-tasklist-Add-surface-loader-function_v43.1.patch @@ -0,0 +1,134 @@ +From b14fa83ef1a23f4df5f11a05ef547fe507701edf Mon Sep 17 00:00:00 2001 +From: Victor Kareh +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 70bbff3..676f2cb 100644 +--- a/libwnck/tasklist.c ++++ b/libwnck/tasklist.c +@@ -235,6 +235,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 + SnDisplay *sn_display; + SnMonitorContext *sn_context; +@@ -1281,6 +1285,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_clear_object (&tasklist->priv->handle); + + G_OBJECT_CLASS (wnck_tasklist_parent_class)->finalize (object); +@@ -1521,6 +1530,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, +@@ -3933,7 +3967,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 82f2d3e..60b90dd 100644 +--- a/libwnck/tasklist.h ++++ b/libwnck/tasklist.h +@@ -146,6 +146,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 cairo_surface_t 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.46.1 + diff --git a/cgmanifest.json b/cgmanifest.json index 59ac79df69a..b42528594eb 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -11541,8 +11541,8 @@ "type": "other", "other": { "name": "libwnck3", - "version": "3.36.0", - "downloadUrl": "http://download.gnome.org/sources/libwnck/3.36/libwnck-3.36.0.tar.xz" + "version": "43.1", + "downloadUrl": "https://download.gnome.org/sources/libwnck/43/libwnck-43.1.tar.xz" } } },