|
|
88c283 |
From 80f79e0cc7509b79b38193a006b0d98d03432044 Mon Sep 17 00:00:00 2001
|
|
|
88c283 |
From: Ray Strode <rstrode@redhat.com>
|
|
|
88c283 |
Date: Mon, 5 Aug 2019 14:39:21 -0400
|
|
|
88c283 |
Subject: [PATCH] iconcache: Avoid xrender picture formats when creating cairo
|
|
|
88c283 |
surface
|
|
|
88c283 |
|
|
|
88c283 |
If an application provides its window icon via wmhints, then mutter
|
|
|
88c283 |
loads the pixmap specified by the application into a cairo xlib surface. When
|
|
|
88c283 |
creating the surface it specifies the visual, indirectly, via an XRender
|
|
|
88c283 |
picture format.
|
|
|
88c283 |
|
|
|
88c283 |
This is suboptimal, since XRender picture formats don't have a way to specify
|
|
|
88c283 |
16bpp depth, which an application may be using.
|
|
|
88c283 |
|
|
|
88c283 |
In particular, applications are likely to use 16bpp depth pixmaps for their
|
|
|
88c283 |
icons, if the video card offers a 16bpp framebuffer/root window.
|
|
|
88c283 |
|
|
|
88c283 |
This commit drops the XRender middleman, and just tells cairo a visual to use
|
|
|
88c283 |
directly.
|
|
|
88c283 |
|
|
|
88c283 |
https://gitlab.gnome.org/GNOME/mutter/merge_requests/715
|
|
|
88c283 |
---
|
|
|
88c283 |
src/x11/iconcache.c | 31 ++++++-------------------------
|
|
|
88c283 |
1 file changed, 6 insertions(+), 25 deletions(-)
|
|
|
88c283 |
|
|
|
88c283 |
diff --git a/src/x11/iconcache.c b/src/x11/iconcache.c
|
|
|
88c283 |
index 15d72da65..521c77b8d 100644
|
|
|
88c283 |
--- a/src/x11/iconcache.c
|
|
|
88c283 |
+++ b/src/x11/iconcache.c
|
|
|
88c283 |
@@ -261,97 +261,78 @@ get_pixmap_geometry (MetaX11Display *x11_display,
|
|
|
88c283 |
Pixmap pixmap,
|
|
|
88c283 |
int *w,
|
|
|
88c283 |
int *h,
|
|
|
88c283 |
int *d)
|
|
|
88c283 |
{
|
|
|
88c283 |
Window root_ignored;
|
|
|
88c283 |
int x_ignored, y_ignored;
|
|
|
88c283 |
guint width, height;
|
|
|
88c283 |
guint border_width_ignored;
|
|
|
88c283 |
guint depth;
|
|
|
88c283 |
|
|
|
88c283 |
if (w)
|
|
|
88c283 |
*w = 1;
|
|
|
88c283 |
if (h)
|
|
|
88c283 |
*h = 1;
|
|
|
88c283 |
if (d)
|
|
|
88c283 |
*d = 1;
|
|
|
88c283 |
|
|
|
88c283 |
XGetGeometry (x11_display->xdisplay,
|
|
|
88c283 |
pixmap, &root_ignored, &x_ignored, &y_ignored,
|
|
|
88c283 |
&width, &height, &border_width_ignored, &depth);
|
|
|
88c283 |
|
|
|
88c283 |
if (w)
|
|
|
88c283 |
*w = width;
|
|
|
88c283 |
if (h)
|
|
|
88c283 |
*h = height;
|
|
|
88c283 |
if (d)
|
|
|
88c283 |
*d = depth;
|
|
|
88c283 |
}
|
|
|
88c283 |
|
|
|
88c283 |
-static int
|
|
|
88c283 |
-standard_pict_format_for_depth (int depth)
|
|
|
88c283 |
-{
|
|
|
88c283 |
- switch (depth)
|
|
|
88c283 |
- {
|
|
|
88c283 |
- case 1:
|
|
|
88c283 |
- return PictStandardA1;
|
|
|
88c283 |
- case 24:
|
|
|
88c283 |
- return PictStandardRGB24;
|
|
|
88c283 |
- case 32:
|
|
|
88c283 |
- return PictStandardARGB32;
|
|
|
88c283 |
- default:
|
|
|
88c283 |
- g_assert_not_reached ();
|
|
|
88c283 |
- }
|
|
|
88c283 |
- return 0;
|
|
|
88c283 |
-}
|
|
|
88c283 |
-
|
|
|
88c283 |
-static XRenderPictFormat *
|
|
|
88c283 |
-pict_format_for_depth (Display *xdisplay, int depth)
|
|
|
88c283 |
-{
|
|
|
88c283 |
- return XRenderFindStandardFormat (xdisplay, standard_pict_format_for_depth (depth));
|
|
|
88c283 |
-}
|
|
|
88c283 |
-
|
|
|
88c283 |
static cairo_surface_t *
|
|
|
88c283 |
surface_from_pixmap (Display *xdisplay, Pixmap xpixmap,
|
|
|
88c283 |
int width, int height)
|
|
|
88c283 |
{
|
|
|
88c283 |
Window root_return;
|
|
|
88c283 |
+ XVisualInfo visual_info;
|
|
|
88c283 |
int x_ret, y_ret;
|
|
|
88c283 |
unsigned int w_ret, h_ret, bw_ret, depth_ret;
|
|
|
88c283 |
|
|
|
88c283 |
if (!XGetGeometry (xdisplay, xpixmap, &root_return,
|
|
|
88c283 |
&x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
|
|
|
88c283 |
return NULL;
|
|
|
88c283 |
|
|
|
88c283 |
- return cairo_xlib_surface_create_with_xrender_format (xdisplay, xpixmap, DefaultScreenOfDisplay (xdisplay),
|
|
|
88c283 |
- pict_format_for_depth (xdisplay, depth_ret), w_ret, h_ret);
|
|
|
88c283 |
+ if (!XMatchVisualInfo (xdisplay, DefaultScreen (xdisplay),
|
|
|
88c283 |
+ depth_ret, TrueColor, &visual_info))
|
|
|
88c283 |
+ return NULL;
|
|
|
88c283 |
+
|
|
|
88c283 |
+ return cairo_xlib_surface_create (xdisplay, xpixmap, visual_info.visual, w_ret, h_ret);
|
|
|
88c283 |
}
|
|
|
88c283 |
|
|
|
88c283 |
static gboolean
|
|
|
88c283 |
try_pixmap_and_mask (MetaX11Display *x11_display,
|
|
|
88c283 |
Pixmap src_pixmap,
|
|
|
88c283 |
Pixmap src_mask,
|
|
|
88c283 |
cairo_surface_t **iconp)
|
|
|
88c283 |
{
|
|
|
88c283 |
Display *xdisplay = x11_display->xdisplay;
|
|
|
88c283 |
cairo_surface_t *icon, *mask = NULL;
|
|
|
88c283 |
int w, h, d;
|
|
|
88c283 |
|
|
|
88c283 |
if (src_pixmap == None)
|
|
|
88c283 |
return FALSE;
|
|
|
88c283 |
|
|
|
88c283 |
meta_x11_error_trap_push (x11_display);
|
|
|
88c283 |
|
|
|
88c283 |
get_pixmap_geometry (x11_display, src_pixmap, &w, &h, &d);
|
|
|
88c283 |
icon = surface_from_pixmap (xdisplay, src_pixmap, w, h);
|
|
|
88c283 |
|
|
|
88c283 |
if (icon && src_mask != None)
|
|
|
88c283 |
{
|
|
|
88c283 |
get_pixmap_geometry (x11_display, src_mask, &w, &h, &d);
|
|
|
88c283 |
|
|
|
88c283 |
if (d == 1)
|
|
|
88c283 |
mask = surface_from_pixmap (xdisplay, src_mask, w, h);
|
|
|
88c283 |
}
|
|
|
88c283 |
|
|
|
88c283 |
meta_x11_error_trap_pop (x11_display);
|
|
|
88c283 |
|
|
|
88c283 |
--
|
|
|
88c283 |
2.21.0
|
|
|
88c283 |
|