1
0
Fork 0

x11: Change the iconcache / window icons to being cairo surfaces

This simplifies the drawing codepath and makes us able to delete
a bunch of GdkPixbuf manipulation.
This commit is contained in:
Jasper St. Pierre 2014-12-31 20:39:36 -08:00
parent f3d30d897f
commit af7f51b992
11 changed files with 154 additions and 386 deletions

View file

@ -120,7 +120,7 @@ meta_core_get (Display *xdisplay,
*((MetaFrameType*)answer) = meta_window_get_frame_type (window); *((MetaFrameType*)answer) = meta_window_get_frame_type (window);
break; break;
case META_CORE_GET_MINI_ICON: case META_CORE_GET_MINI_ICON:
*((GdkPixbuf**)answer) = window->mini_icon; *((cairo_surface_t**)answer) = window->mini_icon;
break; break;
case META_CORE_GET_FRAME_RECT: case META_CORE_GET_FRAME_RECT:
meta_window_get_frame_rect (window, ((MetaRectangle*)answer)); meta_window_get_frame_rect (window, ((MetaRectangle*)answer));

View file

@ -106,8 +106,8 @@ struct _MetaWindow
char *desc; /* used in debug spew */ char *desc; /* used in debug spew */
char *title; char *title;
GdkPixbuf *icon; cairo_surface_t *icon;
GdkPixbuf *mini_icon; cairo_surface_t *mini_icon;
MetaWindowType type; MetaWindowType type;
@ -479,9 +479,9 @@ struct _MetaWindowClass
void (*get_default_skip_hints) (MetaWindow *window, void (*get_default_skip_hints) (MetaWindow *window,
gboolean *skip_taskbar_out, gboolean *skip_taskbar_out,
gboolean *skip_pager_out); gboolean *skip_pager_out);
gboolean (*update_icon) (MetaWindow *window, gboolean (*update_icon) (MetaWindow *window,
GdkPixbuf **icon, cairo_surface_t **icon,
GdkPixbuf **mini_icon); cairo_surface_t **mini_icon);
}; };
/* These differ from window->has_foo_func in that they consider /* These differ from window->has_foo_func in that they consider

View file

@ -244,9 +244,9 @@ meta_window_real_get_default_skip_hints (MetaWindow *window,
} }
static gboolean static gboolean
meta_window_real_update_icon (MetaWindow *window, meta_window_real_update_icon (MetaWindow *window,
GdkPixbuf **icon, cairo_surface_t **icon,
GdkPixbuf **mini_icon) cairo_surface_t **mini_icon)
{ {
*icon = NULL; *icon = NULL;
*mini_icon = NULL; *mini_icon = NULL;
@ -259,10 +259,10 @@ meta_window_finalize (GObject *object)
MetaWindow *window = META_WINDOW (object); MetaWindow *window = META_WINDOW (object);
if (window->icon) if (window->icon)
g_object_unref (G_OBJECT (window->icon)); cairo_surface_destroy (window->icon);
if (window->mini_icon) if (window->mini_icon)
g_object_unref (G_OBJECT (window->mini_icon)); cairo_surface_destroy (window->mini_icon);
if (window->frame_bounds) if (window->frame_bounds)
cairo_region_destroy (window->frame_bounds); cairo_region_destroy (window->frame_bounds);
@ -4890,10 +4890,11 @@ redraw_icon (MetaWindow *window)
meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow); meta_ui_queue_frame_draw (window->screen->ui, window->frame->xwindow);
} }
static GdkPixbuf * static cairo_surface_t *
load_default_window_icon (int size) load_default_window_icon (int size)
{ {
GtkIconTheme *theme = gtk_icon_theme_get_default (); GtkIconTheme *theme = gtk_icon_theme_get_default ();
GdkPixbuf *pixbuf;
const char *icon_name; const char *icon_name;
if (gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME)) if (gtk_icon_theme_has_icon (theme, META_DEFAULT_ICON_NAME))
@ -4901,13 +4902,14 @@ load_default_window_icon (int size)
else else
icon_name = "image-missing"; icon_name = "image-missing";
return gtk_icon_theme_load_icon (theme, icon_name, size, 0, NULL); pixbuf = gtk_icon_theme_load_icon (theme, icon_name, size, 0, NULL);
return gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL);
} }
static GdkPixbuf * static cairo_surface_t *
get_default_window_icon (void) get_default_window_icon (void)
{ {
static GdkPixbuf *default_icon = NULL; static cairo_surface_t *default_icon = NULL;
if (default_icon == NULL) if (default_icon == NULL)
{ {
@ -4915,13 +4917,13 @@ get_default_window_icon (void)
g_assert (default_icon); g_assert (default_icon);
} }
return g_object_ref (default_icon); return cairo_surface_reference (default_icon);
} }
static GdkPixbuf * static cairo_surface_t *
get_default_mini_icon (void) get_default_mini_icon (void)
{ {
static GdkPixbuf *default_icon = NULL; static cairo_surface_t *default_icon = NULL;
if (default_icon == NULL) if (default_icon == NULL)
{ {
@ -4929,7 +4931,7 @@ get_default_mini_icon (void)
g_assert (default_icon); g_assert (default_icon);
} }
return g_object_ref (default_icon); return cairo_surface_reference (default_icon);
} }
static void static void
@ -4937,8 +4939,8 @@ meta_window_update_icon_now (MetaWindow *window,
gboolean force) gboolean force)
{ {
gboolean changed; gboolean changed;
GdkPixbuf *icon = NULL; cairo_surface_t *icon = NULL;
GdkPixbuf *mini_icon; cairo_surface_t *mini_icon;
g_return_if_fail (!window->override_redirect); g_return_if_fail (!window->override_redirect);
@ -4947,14 +4949,14 @@ meta_window_update_icon_now (MetaWindow *window,
if (changed || force) if (changed || force)
{ {
if (window->icon) if (window->icon)
g_object_unref (window->icon); cairo_surface_destroy (window->icon);
if (icon) if (icon)
window->icon = icon; window->icon = icon;
else else
window->icon = get_default_window_icon (); window->icon = get_default_window_icon ();
if (window->mini_icon) if (window->mini_icon)
g_object_unref (window->mini_icon); cairo_surface_destroy (window->mini_icon);
if (mini_icon) if (mini_icon)
window->mini_icon = mini_icon; window->mini_icon = mini_icon;
else else

View file

@ -1673,7 +1673,7 @@ meta_frames_paint (MetaFrames *frames,
{ {
MetaFrameFlags flags; MetaFrameFlags flags;
MetaFrameType type; MetaFrameType type;
GdkPixbuf *mini_icon; cairo_surface_t *mini_icon;
int w, h; int w, h;
MetaButtonState button_states[META_BUTTON_TYPE_LAST]; MetaButtonState button_states[META_BUTTON_TYPE_LAST];
int i; int i;

View file

@ -265,7 +265,7 @@ void meta_theme_draw_frame (MetaTheme *theme,
int text_height, int text_height,
const MetaButtonLayout *button_layout, const MetaButtonLayout *button_layout,
MetaButtonState button_states[META_BUTTON_TYPE_LAST], MetaButtonState button_states[META_BUTTON_TYPE_LAST],
GdkPixbuf *mini_icon); cairo_surface_t *mini_icon);
void meta_theme_get_frame_borders (MetaTheme *theme, void meta_theme_get_frame_borders (MetaTheme *theme,
MetaStyleInfo *style_info, MetaStyleInfo *style_info,

View file

@ -725,7 +725,7 @@ meta_frame_layout_draw_with_style (MetaFrameLayout *layout,
PangoLayout *title_layout, PangoLayout *title_layout,
MetaFrameFlags flags, MetaFrameFlags flags,
MetaButtonState button_states[META_BUTTON_TYPE_LAST], MetaButtonState button_states[META_BUTTON_TYPE_LAST],
GdkPixbuf *mini_icon) cairo_surface_t *mini_icon)
{ {
GtkStyleContext *style; GtkStyleContext *style;
GtkStateFlags state; GtkStateFlags state;
@ -810,7 +810,7 @@ meta_frame_layout_draw_with_style (MetaFrameLayout *layout,
if (gdk_cairo_get_clip_rectangle (cr, NULL)) if (gdk_cairo_get_clip_rectangle (cr, NULL))
{ {
GdkPixbuf *pixbuf = NULL; cairo_surface_t *surface = NULL;
const char *icon_name = NULL; const char *icon_name = NULL;
gtk_render_background (style, cr, gtk_render_background (style, cr,
@ -838,7 +838,7 @@ meta_frame_layout_draw_with_style (MetaFrameLayout *layout,
icon_name = "open-menu-symbolic"; icon_name = "open-menu-symbolic";
break; break;
case META_BUTTON_TYPE_APPMENU: case META_BUTTON_TYPE_APPMENU:
pixbuf = g_object_ref (mini_icon); surface = cairo_surface_reference (mini_icon);
break; break;
default: default:
icon_name = NULL; icon_name = NULL;
@ -849,18 +849,20 @@ meta_frame_layout_draw_with_style (MetaFrameLayout *layout,
{ {
GtkIconTheme *theme = gtk_icon_theme_get_default (); GtkIconTheme *theme = gtk_icon_theme_get_default ();
GtkIconInfo *info; GtkIconInfo *info;
GdkPixbuf *pixbuf;
info = gtk_icon_theme_lookup_icon (theme, icon_name, layout->icon_size, 0); info = gtk_icon_theme_lookup_icon (theme, icon_name, layout->icon_size, 0);
pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL); pixbuf = gtk_icon_info_load_symbolic_for_context (info, style, NULL, NULL);
surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 1, NULL);
} }
if (pixbuf) if (surface)
{ {
float width, height; float width, height;
int x, y; int x, y;
width = gdk_pixbuf_get_width (pixbuf); width = cairo_image_surface_get_width (surface);
height = gdk_pixbuf_get_height (pixbuf); height = cairo_image_surface_get_height (surface);
x = button_rect.x + (button_rect.width - width) / 2; x = button_rect.x + (button_rect.width - width) / 2;
y = button_rect.y + (button_rect.height - height) / 2; y = button_rect.y + (button_rect.height - height) / 2;
@ -868,11 +870,10 @@ meta_frame_layout_draw_with_style (MetaFrameLayout *layout,
cairo_scale (cr, cairo_scale (cr,
width / layout->icon_size, width / layout->icon_size,
height / layout->icon_size); height / layout->icon_size);
cairo_set_source_surface (cr, surface, 0, 0);
gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
cairo_paint (cr); cairo_paint (cr);
g_object_unref (pixbuf); cairo_surface_destroy (surface);
} }
} }
cairo_restore (cr); cairo_restore (cr);
@ -1180,7 +1181,7 @@ meta_theme_draw_frame (MetaTheme *theme,
int text_height, int text_height,
const MetaButtonLayout *button_layout, const MetaButtonLayout *button_layout,
MetaButtonState button_states[META_BUTTON_TYPE_LAST], MetaButtonState button_states[META_BUTTON_TYPE_LAST],
GdkPixbuf *mini_icon) cairo_surface_t *mini_icon)
{ {
MetaFrameGeometry fgeom; MetaFrameGeometry fgeom;
MetaFrameLayout *layout; MetaFrameLayout *layout;

View file

@ -500,56 +500,6 @@ meta_ui_set_frame_title (MetaUI *ui,
meta_frames_set_title (ui->frames, xwindow, title); meta_frames_set_title (ui->frames, xwindow, title);
} }
GdkPixbuf*
meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
int src_x,
int src_y,
int width,
int height)
{
cairo_surface_t *surface;
Display *display;
Window root_return;
int x_ret, y_ret;
unsigned int w_ret, h_ret, bw_ret, depth_ret;
XWindowAttributes attrs;
GdkPixbuf *retval;
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
if (!XGetGeometry (display, xpixmap, &root_return,
&x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
return NULL;
if (depth_ret == 1)
{
surface = cairo_xlib_surface_create_for_bitmap (display,
xpixmap,
GDK_SCREEN_XSCREEN (gdk_screen_get_default ()),
w_ret,
h_ret);
}
else
{
if (!XGetWindowAttributes (display, root_return, &attrs))
return NULL;
surface = cairo_xlib_surface_create (display,
xpixmap,
attrs.visual,
w_ret, h_ret);
}
retval = gdk_pixbuf_get_from_surface (surface,
src_x,
src_y,
width,
height);
cairo_surface_destroy (surface);
return retval;
}
gboolean gboolean
meta_ui_window_should_not_cause_focus (Display *xdisplay, meta_ui_window_should_not_cause_focus (Display *xdisplay,
Window xwindow) Window xwindow)

View file

@ -101,13 +101,6 @@ void meta_ui_repaint_frame (MetaUI *ui,
Window xwindow); Window xwindow);
/* FIXME these lack a display arg */
GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (Pixmap xpixmap,
int src_x,
int src_y,
int width,
int height);
gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay, gboolean meta_ui_window_should_not_cause_focus (Display *xdisplay,
Window xwindow); Window xwindow);

View file

@ -19,14 +19,16 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>. * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/ */
#include <config.h> #include "config.h"
#include "iconcache.h" #include "iconcache.h"
#include "ui.h"
#include <meta/errors.h> #include <meta/errors.h>
#include <X11/Xatom.h> #include <cairo.h>
#include <cairo-xlib.h>
/* The icon-reading code is also in libwnck, please sync bugfixes */ #include <X11/Xatom.h>
static gboolean static gboolean
find_largest_sizes (gulong *data, find_largest_sizes (gulong *data,
@ -156,51 +158,40 @@ find_best_size (gulong *data,
return FALSE; return FALSE;
} }
static void static cairo_surface_t *
argbdata_to_pixdata (gulong *argb_data, int len, guchar **pixdata) argbdata_to_surface (gulong *argb_data, int w, int h)
{ {
guchar *p; cairo_surface_t *surface;
int i; int y, x, stride;
uint8_t *data;
*pixdata = g_new (guchar, len * 4); surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
p = *pixdata; stride = cairo_image_surface_get_stride (surface);
data = cairo_image_surface_get_data (surface);
/* One could speed this up a lot. */ /* One could speed this up a lot. */
i = 0; for (y = 0; y < h; y++)
while (i < len)
{ {
guint argb; for (x = 0; x < w; x++)
guint rgba; {
uint32_t *p = (uint32_t *) &data[y * stride + x];
argb = argb_data[i]; gulong *d = &argb_data[y * w + x];
rgba = (argb << 8) | (argb >> 24); *p = *d;
}
*p = rgba >> 24;
++p;
*p = (rgba >> 16) & 0xff;
++p;
*p = (rgba >> 8) & 0xff;
++p;
*p = rgba & 0xff;
++p;
++i;
} }
return surface;
} }
static gboolean static gboolean
read_rgb_icon (MetaDisplay *display, read_rgb_icon (MetaDisplay *display,
Window xwindow, Window xwindow,
int ideal_width, int ideal_width,
int ideal_height, int ideal_height,
int ideal_mini_width, int ideal_mini_width,
int ideal_mini_height, int ideal_mini_height,
int *width, cairo_surface_t **icon,
int *height, cairo_surface_t **mini_icon)
guchar **pixdata,
int *mini_width,
int *mini_height,
guchar **mini_pixdata)
{ {
Atom type; Atom type;
int format; int format;
@ -253,26 +244,14 @@ read_rgb_icon (MetaDisplay *display,
return FALSE; return FALSE;
} }
*width = w; *icon = argbdata_to_surface (best, w, h);
*height = h; *mini_icon = argbdata_to_surface (best_mini, mini_w, mini_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);
XFree (data); XFree (data);
return TRUE; return TRUE;
} }
static void
free_pixels (guchar *pixels, gpointer data)
{
g_free (pixels);
}
static void static void
get_pixmap_geometry (MetaDisplay *display, get_pixmap_geometry (MetaDisplay *display,
Pixmap pixmap, Pixmap pixmap,
@ -305,96 +284,44 @@ get_pixmap_geometry (MetaDisplay *display,
*d = depth; *d = depth;
} }
static void static cairo_surface_t *
apply_foreground_background (GdkPixbuf *pixbuf) surface_from_pixmap (Display *xdisplay, Pixmap xpixmap,
int width, int height)
{ {
int w, h; cairo_surface_t *surface;
int i, j; Window root_return;
guchar *pixels; int x_ret, y_ret;
int stride; unsigned int w_ret, h_ret, bw_ret, depth_ret;
XWindowAttributes attrs;
w = gdk_pixbuf_get_width (pixbuf); if (!XGetGeometry (xdisplay, xpixmap, &root_return,
h = gdk_pixbuf_get_height (pixbuf); &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
pixels = gdk_pixbuf_get_pixels (pixbuf); return NULL;
stride = gdk_pixbuf_get_rowstride (pixbuf);
i = 0; if (depth_ret == 1)
while (i < h)
{ {
j = 0; surface = cairo_xlib_surface_create_for_bitmap (xdisplay, xpixmap, DefaultScreenOfDisplay (xdisplay),
while (j < w) w_ret, h_ret);
{
guchar *p = pixels + i * stride + j * 4;
if (p[3] == 0)
p[0] = p[1] = p[2] = 0xff; /* white background */
else
p[0] = p[1] = p[2] = 0x00; /* black foreground */
p[3] = 0xff;
++j;
}
++i;
} }
} else
static GdkPixbuf*
apply_mask (GdkPixbuf *pixbuf,
GdkPixbuf *mask)
{
int w, h;
int i, j;
GdkPixbuf *with_alpha;
guchar *src;
guchar *dest;
int src_stride;
int dest_stride;
w = MIN (gdk_pixbuf_get_width (mask), gdk_pixbuf_get_width (pixbuf));
h = MIN (gdk_pixbuf_get_height (mask), gdk_pixbuf_get_height (pixbuf));
with_alpha = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0);
dest = gdk_pixbuf_get_pixels (with_alpha);
src = gdk_pixbuf_get_pixels (mask);
dest_stride = gdk_pixbuf_get_rowstride (with_alpha);
src_stride = gdk_pixbuf_get_rowstride (mask);
i = 0;
while (i < h)
{ {
j = 0; if (!XGetWindowAttributes (xdisplay, root_return, &attrs))
while (j < w) return NULL;
{
guchar *s = src + i * src_stride + j * 4;
guchar *d = dest + i * dest_stride + j * 4;
d[3] = s[3]; surface = cairo_xlib_surface_create (xdisplay, xpixmap, attrs.visual, w_ret, h_ret);
++j;
}
++i;
} }
return with_alpha; return surface;
} }
static gboolean static gboolean
try_pixmap_and_mask (MetaDisplay *display, try_pixmap_and_mask (MetaDisplay *display,
Pixmap src_pixmap, Pixmap src_pixmap,
Pixmap src_mask, Pixmap src_mask,
GdkPixbuf **iconp, cairo_surface_t **iconp)
int ideal_width,
int ideal_height,
GdkPixbuf **mini_iconp,
int ideal_mini_width,
int ideal_mini_height)
{ {
GdkPixbuf *unscaled = NULL; Display *xdisplay = display->xdisplay;
GdkPixbuf *mask = NULL; cairo_surface_t *icon, *mask = NULL;
int w, h, d; int w, h, d;
if (src_pixmap == None) if (src_pixmap == None)
@ -403,72 +330,48 @@ try_pixmap_and_mask (MetaDisplay *display,
meta_error_trap_push (display); meta_error_trap_push (display);
get_pixmap_geometry (display, src_pixmap, &w, &h, &d); get_pixmap_geometry (display, src_pixmap, &w, &h, &d);
icon = surface_from_pixmap (xdisplay, src_pixmap, w, h);
unscaled = meta_gdk_pixbuf_get_from_pixmap (src_pixmap, if (icon && src_mask != None)
0, 0,
w, h);
/* A depth 1 pixmap has 0 background, and 1 foreground, but
* cairo and meta_gdk_pixbuf_get_from_pixmap consider it
* to be 0 transparent, 1 opaque */
if (d == 1)
apply_foreground_background (unscaled);
if (unscaled && src_mask != None)
{ {
get_pixmap_geometry (display, src_mask, &w, &h, &d); get_pixmap_geometry (display, src_mask, &w, &h, &d);
if (d == 1) if (d == 1)
mask = meta_gdk_pixbuf_get_from_pixmap (src_mask, mask = surface_from_pixmap (xdisplay, src_mask, w, h);
0, 0,
w, h);
} }
meta_error_trap_pop (display); meta_error_trap_pop (display);
if (mask) if (icon && mask)
{ {
GdkPixbuf *masked; cairo_surface_t *masked;
cairo_t *cr;
masked = apply_mask (unscaled, mask); masked = cairo_surface_create_similar_image (icon,
g_object_unref (G_OBJECT (unscaled)); CAIRO_FORMAT_ARGB32,
unscaled = masked; cairo_image_surface_get_width (icon),
cairo_image_surface_get_height (icon));
cr = cairo_create (masked);
g_object_unref (G_OBJECT (mask)); cairo_set_source_surface (cr, icon, 0, 0);
mask = NULL; cairo_mask_surface (cr, mask, 0, 0);
cairo_destroy (cr);
cairo_surface_destroy (icon);
cairo_surface_destroy (mask);
icon = masked;
} }
if (unscaled) if (icon)
{ {
*iconp = *iconp = icon;
gdk_pixbuf_scale_simple (unscaled, return TRUE;
ideal_width > 0 ? ideal_width :
gdk_pixbuf_get_width (unscaled),
ideal_height > 0 ? ideal_height :
gdk_pixbuf_get_height (unscaled),
GDK_INTERP_BILINEAR);
*mini_iconp =
gdk_pixbuf_scale_simple (unscaled,
ideal_mini_width > 0 ? ideal_mini_width :
gdk_pixbuf_get_width (unscaled),
ideal_mini_height > 0 ? ideal_mini_height :
gdk_pixbuf_get_height (unscaled),
GDK_INTERP_BILINEAR);
g_object_unref (G_OBJECT (unscaled));
if (*iconp && *mini_iconp)
return TRUE;
else
{
if (*iconp)
g_object_unref (G_OBJECT (*iconp));
if (*mini_iconp)
g_object_unref (G_OBJECT (*mini_iconp));
return FALSE;
}
} }
else else
return FALSE; {
return FALSE;
}
} }
static void static void
@ -562,74 +465,18 @@ meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache)
return FALSE; return FALSE;
} }
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)
{
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;
}
gboolean gboolean
meta_read_icons (MetaScreen *screen, meta_read_icons (MetaScreen *screen,
Window xwindow, Window xwindow,
MetaIconCache *icon_cache, MetaIconCache *icon_cache,
Pixmap wm_hints_pixmap, Pixmap wm_hints_pixmap,
Pixmap wm_hints_mask, Pixmap wm_hints_mask,
GdkPixbuf **iconp, cairo_surface_t **iconp,
int ideal_width, int ideal_width,
int ideal_height, int ideal_height,
GdkPixbuf **mini_iconp, cairo_surface_t **mini_iconp,
int ideal_mini_width, int ideal_mini_width,
int ideal_mini_height) int ideal_mini_height)
{ {
/* Return value is whether the icon changed */ /* Return value is whether the icon changed */
@ -653,37 +500,15 @@ meta_read_icons (MetaScreen *screen,
if (icon_cache->origin <= USING_NET_WM_ICON && if (icon_cache->origin <= USING_NET_WM_ICON &&
icon_cache->net_wm_icon_dirty) icon_cache->net_wm_icon_dirty)
{ {
guchar *pixdata;
int w, h;
guchar *mini_pixdata;
int mini_w, mini_h;
icon_cache->net_wm_icon_dirty = FALSE; icon_cache->net_wm_icon_dirty = FALSE;
if (read_rgb_icon (screen->display, xwindow, if (read_rgb_icon (screen->display, xwindow,
ideal_width, ideal_height, ideal_width, ideal_height,
ideal_mini_width, ideal_mini_height, ideal_mini_width, ideal_mini_height,
&w, &h, &pixdata, iconp, mini_iconp))
&mini_w, &mini_h, &mini_pixdata))
{ {
*iconp = scaled_from_pixdata (pixdata, w, h, icon_cache->origin = USING_NET_WM_ICON;
ideal_width, ideal_height); return TRUE;
*mini_iconp = scaled_from_pixdata (mini_pixdata, mini_w, mini_h,
ideal_mini_width, ideal_mini_height);
if (*iconp && *mini_iconp)
{
icon_cache->origin = USING_NET_WM_ICON;
return TRUE;
}
else
{
if (*iconp)
g_object_unref (G_OBJECT (*iconp));
if (*mini_iconp)
g_object_unref (G_OBJECT (*mini_iconp));
}
} }
} }
@ -706,11 +531,9 @@ meta_read_icons (MetaScreen *screen,
mask != icon_cache->prev_mask) && mask != icon_cache->prev_mask) &&
pixmap != None) pixmap != None)
{ {
if (try_pixmap_and_mask (screen->display, if (try_pixmap_and_mask (screen->display, pixmap, mask, iconp))
pixmap, mask,
iconp, ideal_width, ideal_height,
mini_iconp, ideal_mini_width, ideal_mini_height))
{ {
*mini_iconp = cairo_surface_reference (*iconp);
icon_cache->prev_pixmap = pixmap; icon_cache->prev_pixmap = pixmap;
icon_cache->prev_mask = mask; icon_cache->prev_mask = mask;
icon_cache->origin = USING_WM_HINTS; icon_cache->origin = USING_WM_HINTS;
@ -733,10 +556,9 @@ meta_read_icons (MetaScreen *screen,
mask != icon_cache->prev_mask) && mask != icon_cache->prev_mask) &&
pixmap != None) pixmap != None)
{ {
if (try_pixmap_and_mask (screen->display, pixmap, mask, if (try_pixmap_and_mask (screen->display, pixmap, mask, iconp))
iconp, ideal_width, ideal_height,
mini_iconp, ideal_mini_width, ideal_mini_height))
{ {
*mini_iconp = cairo_surface_reference (*iconp);
icon_cache->prev_pixmap = pixmap; icon_cache->prev_pixmap = pixmap;
icon_cache->prev_mask = mask; icon_cache->prev_mask = mask;
icon_cache->origin = USING_KWM_WIN_ICON; icon_cache->origin = USING_KWM_WIN_ICON;

View file

@ -56,17 +56,17 @@ void meta_icon_cache_property_changed (MetaIconCache *icon_cache,
Atom atom); Atom atom);
gboolean meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache); gboolean meta_icon_cache_get_icon_invalidated (MetaIconCache *icon_cache);
gboolean meta_read_icons (MetaScreen *screen, gboolean meta_read_icons (MetaScreen *screen,
Window xwindow, Window xwindow,
MetaIconCache *icon_cache, MetaIconCache *icon_cache,
Pixmap wm_hints_pixmap, Pixmap wm_hints_pixmap,
Pixmap wm_hints_mask, Pixmap wm_hints_mask,
GdkPixbuf **iconp, cairo_surface_t **iconp,
int ideal_width, int ideal_width,
int ideal_height, int ideal_height,
GdkPixbuf **mini_iconp, cairo_surface_t **mini_iconp,
int ideal_mini_width, int ideal_mini_width,
int ideal_mini_height); int ideal_mini_height);
#endif #endif

View file

@ -1459,9 +1459,9 @@ meta_window_x11_get_default_skip_hints (MetaWindow *window,
} }
static gboolean static gboolean
meta_window_x11_update_icon (MetaWindow *window, meta_window_x11_update_icon (MetaWindow *window,
GdkPixbuf **icon, cairo_surface_t **icon,
GdkPixbuf **mini_icon) cairo_surface_t **mini_icon)
{ {
MetaWindowX11 *window_x11 = META_WINDOW_X11 (window); MetaWindowX11 *window_x11 = META_WINDOW_X11 (window);
MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11); MetaWindowX11Private *priv = meta_window_x11_get_instance_private (window_x11);