mirror of
https://github.com/brl/mutter.git
synced 2025-02-19 14:44:10 +00:00
half-ass implementation of getting pixmap icons (WM_NORMAL_HINTS and
2001-08-22 Havoc Pennington <hp@pobox.com> * src/window.c (update_icon): half-ass implementation of getting pixmap icons (WM_NORMAL_HINTS and KWM_WIN_ICON). Ignores mask for now, with possibly ugly results for some apps. (read_rgb_icon): fixage
This commit is contained in:
parent
f562e65d5f
commit
e51c12d1cd
@ -1,3 +1,11 @@
|
|||||||
|
2001-08-22 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
|
* src/window.c (update_icon): half-ass implementation of
|
||||||
|
getting pixmap icons (WM_NORMAL_HINTS and KWM_WIN_ICON).
|
||||||
|
Ignores mask for now, with possibly ugly results for
|
||||||
|
some apps.
|
||||||
|
(read_rgb_icon): fixage
|
||||||
|
|
||||||
2001-08-19 Havoc Pennington <hp@pobox.com>
|
2001-08-19 Havoc Pennington <hp@pobox.com>
|
||||||
|
|
||||||
* src/window.c: add a "fullscreen" semantic type; if a window
|
* src/window.c: add a "fullscreen" semantic type; if a window
|
||||||
|
@ -133,7 +133,8 @@ meta_display_open (const char *name)
|
|||||||
"_NET_WM_ICON",
|
"_NET_WM_ICON",
|
||||||
"_NET_WM_ICON_GEOMETRY",
|
"_NET_WM_ICON_GEOMETRY",
|
||||||
"UTF8_STRING",
|
"UTF8_STRING",
|
||||||
"WM_ICON_SIZE"
|
"WM_ICON_SIZE",
|
||||||
|
"_KWM_WIN_ICON"
|
||||||
};
|
};
|
||||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||||
|
|
||||||
@ -218,6 +219,7 @@ meta_display_open (const char *name)
|
|||||||
display->atom_net_wm_icon_geometry = atoms[38];
|
display->atom_net_wm_icon_geometry = atoms[38];
|
||||||
display->atom_utf8_string = atoms[39];
|
display->atom_utf8_string = atoms[39];
|
||||||
display->atom_wm_icon_size = atoms[40];
|
display->atom_wm_icon_size = atoms[40];
|
||||||
|
display->atom_kwm_win_icon = atoms[41];
|
||||||
|
|
||||||
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
|
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
|
||||||
* created in screen_new
|
* created in screen_new
|
||||||
|
@ -98,6 +98,7 @@ struct _MetaDisplay
|
|||||||
Atom atom_net_wm_icon_geometry;
|
Atom atom_net_wm_icon_geometry;
|
||||||
Atom atom_utf8_string;
|
Atom atom_utf8_string;
|
||||||
Atom atom_wm_icon_size;
|
Atom atom_wm_icon_size;
|
||||||
|
Atom atom_kwm_win_icon;
|
||||||
|
|
||||||
/* This is the actual window from focus events,
|
/* This is the actual window from focus events,
|
||||||
* not the one we last set
|
* not the one we last set
|
||||||
|
219
src/window.c
219
src/window.c
@ -61,6 +61,7 @@ static int update_initial_workspace (MetaWindow *window);
|
|||||||
static int update_icon_name (MetaWindow *window);
|
static int update_icon_name (MetaWindow *window);
|
||||||
static int update_icon (MetaWindow *window,
|
static int update_icon (MetaWindow *window,
|
||||||
gboolean reread_rgb_icon);
|
gboolean reread_rgb_icon);
|
||||||
|
static int update_kwm_icon (MetaWindow *window);
|
||||||
static void recalc_window_type (MetaWindow *window);
|
static void recalc_window_type (MetaWindow *window);
|
||||||
static void recalc_window_features (MetaWindow *window);
|
static void recalc_window_features (MetaWindow *window);
|
||||||
static int set_wm_state (MetaWindow *window,
|
static int set_wm_state (MetaWindow *window,
|
||||||
@ -319,6 +320,9 @@ meta_window_new (MetaDisplay *display, Window xwindow,
|
|||||||
window->icon_pixmap = None;
|
window->icon_pixmap = None;
|
||||||
window->icon_mask = None;
|
window->icon_mask = None;
|
||||||
|
|
||||||
|
window->kwm_pixmap = None;
|
||||||
|
window->kwm_mask = None;
|
||||||
|
|
||||||
window->using_rgb_icon = FALSE;
|
window->using_rgb_icon = FALSE;
|
||||||
|
|
||||||
window->type = META_WINDOW_NORMAL;
|
window->type = META_WINDOW_NORMAL;
|
||||||
@ -342,7 +346,8 @@ meta_window_new (MetaDisplay *display, Window xwindow,
|
|||||||
update_net_wm_type (window);
|
update_net_wm_type (window);
|
||||||
update_initial_workspace (window);
|
update_initial_workspace (window);
|
||||||
update_icon_name (window);
|
update_icon_name (window);
|
||||||
/* should come after wm_hints */
|
update_kwm_icon (window);
|
||||||
|
/* should come after wm_hints and kwm_icon updates */
|
||||||
update_icon (window, TRUE);
|
update_icon (window, TRUE);
|
||||||
|
|
||||||
if (!window->mapped &&
|
if (!window->mapped &&
|
||||||
@ -2335,6 +2340,7 @@ process_property_notify (MetaWindow *window,
|
|||||||
meta_verbose ("Property notify on %s for WM_HINTS\n", window->desc);
|
meta_verbose ("Property notify on %s for WM_HINTS\n", window->desc);
|
||||||
|
|
||||||
update_wm_hints (window);
|
update_wm_hints (window);
|
||||||
|
update_icon (window, FALSE);
|
||||||
|
|
||||||
meta_window_queue_move_resize (window);
|
meta_window_queue_move_resize (window);
|
||||||
}
|
}
|
||||||
@ -2400,6 +2406,12 @@ process_property_notify (MetaWindow *window,
|
|||||||
meta_verbose ("Property notify on %s for NET_WM_ICON\n", window->desc);
|
meta_verbose ("Property notify on %s for NET_WM_ICON\n", window->desc);
|
||||||
update_icon (window, TRUE);
|
update_icon (window, TRUE);
|
||||||
}
|
}
|
||||||
|
else if (event->atom == window->display->atom_kwm_win_icon)
|
||||||
|
{
|
||||||
|
meta_verbose ("Property notify on %s for KWM_WIN_ICON\n", window->desc);
|
||||||
|
update_kwm_icon (window);
|
||||||
|
update_icon (window, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -2786,9 +2798,9 @@ update_wm_hints (MetaWindow *window)
|
|||||||
update_icon (window, FALSE);
|
update_icon (window, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%ld\n",
|
meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%lx icon: 0x%lx\n",
|
||||||
window->input, window->initially_iconic,
|
window->input, window->initially_iconic,
|
||||||
window->xgroup_leader);
|
window->xgroup_leader, window->icon_pixmap);
|
||||||
|
|
||||||
XFree (hints);
|
XFree (hints);
|
||||||
}
|
}
|
||||||
@ -3522,7 +3534,7 @@ update_icon_name (MetaWindow *window)
|
|||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
find_best_size (gulong *data,
|
find_best_size (gulong *data,
|
||||||
gulong nitems,
|
int nitems,
|
||||||
int *width,
|
int *width,
|
||||||
int *height,
|
int *height,
|
||||||
gulong **start)
|
gulong **start)
|
||||||
@ -3531,6 +3543,10 @@ find_best_size (gulong *data,
|
|||||||
int best_h;
|
int best_h;
|
||||||
gulong *best_start;
|
gulong *best_start;
|
||||||
|
|
||||||
|
*width = 0;
|
||||||
|
*height = 0;
|
||||||
|
*start = NULL;
|
||||||
|
|
||||||
best_w = 0;
|
best_w = 0;
|
||||||
best_h = 0;
|
best_h = 0;
|
||||||
best_start = NULL;
|
best_start = NULL;
|
||||||
@ -3540,6 +3556,8 @@ find_best_size (gulong *data,
|
|||||||
int w, h;
|
int w, h;
|
||||||
gboolean replace;
|
gboolean replace;
|
||||||
|
|
||||||
|
meta_debug_spew ("n_items = %d\n", nitems);
|
||||||
|
|
||||||
replace = FALSE;
|
replace = FALSE;
|
||||||
|
|
||||||
if (nitems < 3)
|
if (nitems < 3)
|
||||||
@ -3551,10 +3569,12 @@ find_best_size (gulong *data,
|
|||||||
w = data[0];
|
w = data[0];
|
||||||
h = data[1];
|
h = data[1];
|
||||||
|
|
||||||
|
meta_debug_spew ("w = %d h = %d\n", w, h);
|
||||||
|
|
||||||
if (nitems < ((w * h) + 2))
|
if (nitems < ((w * h) + 2))
|
||||||
{
|
{
|
||||||
meta_verbose ("_NET_WM_ICON contained too little data\n");
|
meta_verbose ("_NET_WM_ICON contained too little data?\n");
|
||||||
return FALSE;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best_start == NULL)
|
if (best_start == NULL)
|
||||||
@ -3592,6 +3612,7 @@ find_best_size (gulong *data,
|
|||||||
best_h = h;
|
best_h = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data += (w * h) + 2;
|
||||||
nitems -= (w * h) + 2;
|
nitems -= (w * h) + 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3655,7 +3676,7 @@ read_rgb_icon (MetaWindow *window,
|
|||||||
*width = w;
|
*width = w;
|
||||||
*height = h;
|
*height = h;
|
||||||
|
|
||||||
*pixdata = g_new (guchar, w * h);
|
*pixdata = g_new (guchar, w * h * 4);
|
||||||
p = *pixdata;
|
p = *pixdata;
|
||||||
|
|
||||||
/* One could speed this up a lot. */
|
/* One could speed this up a lot. */
|
||||||
@ -3666,7 +3687,7 @@ read_rgb_icon (MetaWindow *window,
|
|||||||
guint rgba;
|
guint rgba;
|
||||||
|
|
||||||
argb = best[i];
|
argb = best[i];
|
||||||
rgba = (argb << 8) & (argb >> 24);
|
rgba = (argb << 8) | (argb >> 24);
|
||||||
|
|
||||||
*p = rgba >> 24;
|
*p = rgba >> 24;
|
||||||
++p;
|
++p;
|
||||||
@ -3701,6 +3722,60 @@ free_pixels (guchar *pixels, gpointer data)
|
|||||||
g_free (pixels);
|
g_free (pixels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
replace_icon (MetaWindow *window,
|
||||||
|
GdkPixbuf *unscaled)
|
||||||
|
{
|
||||||
|
if (gdk_pixbuf_get_width (unscaled) != META_ICON_WIDTH ||
|
||||||
|
gdk_pixbuf_get_height (unscaled) != META_ICON_HEIGHT)
|
||||||
|
{
|
||||||
|
/* FIXME should keep aspect ratio, but for now assuming
|
||||||
|
* a square source icon
|
||||||
|
*/
|
||||||
|
window->icon = gdk_pixbuf_scale_simple (unscaled,
|
||||||
|
META_ICON_WIDTH,
|
||||||
|
META_ICON_HEIGHT,
|
||||||
|
GDK_INTERP_BILINEAR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_object_ref (G_OBJECT (unscaled));
|
||||||
|
window->icon = unscaled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_pixmap_geometry (MetaDisplay *display,
|
||||||
|
Pixmap pixmap,
|
||||||
|
int *w,
|
||||||
|
int *h,
|
||||||
|
int *d)
|
||||||
|
{
|
||||||
|
Window root_ignored;
|
||||||
|
int x_ignored, y_ignored;
|
||||||
|
guint width, height;
|
||||||
|
guint border_width_ignored;
|
||||||
|
guint depth;
|
||||||
|
|
||||||
|
if (w)
|
||||||
|
*w = 1;
|
||||||
|
if (h)
|
||||||
|
*h = 1;
|
||||||
|
if (d)
|
||||||
|
*d = 1;
|
||||||
|
|
||||||
|
XGetGeometry (display->xdisplay,
|
||||||
|
pixmap, &root_ignored, &x_ignored, &y_ignored,
|
||||||
|
&width, &height, &border_width_ignored, &depth);
|
||||||
|
|
||||||
|
if (w)
|
||||||
|
*w = width;
|
||||||
|
if (h)
|
||||||
|
*h = height;
|
||||||
|
if (d)
|
||||||
|
*d = depth;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
update_icon (MetaWindow *window,
|
update_icon (MetaWindow *window,
|
||||||
gboolean reload_rgb_icon)
|
gboolean reload_rgb_icon)
|
||||||
@ -3717,36 +3792,21 @@ update_icon (MetaWindow *window,
|
|||||||
{
|
{
|
||||||
GdkPixbuf *unscaled;
|
GdkPixbuf *unscaled;
|
||||||
|
|
||||||
meta_verbose ("successfully read RGBA icon fro _NET_WM_ICON\n");
|
meta_verbose ("successfully read RGBA icon from _NET_WM_ICON, using w = %d h = %d\n", w, h);
|
||||||
|
|
||||||
window->using_rgb_icon = TRUE;
|
window->using_rgb_icon = TRUE;
|
||||||
|
|
||||||
clear_icon (window);
|
|
||||||
|
|
||||||
unscaled = gdk_pixbuf_new_from_data (pixdata,
|
unscaled = gdk_pixbuf_new_from_data (pixdata,
|
||||||
GDK_COLORSPACE_RGB,
|
GDK_COLORSPACE_RGB,
|
||||||
TRUE,
|
TRUE,
|
||||||
8,
|
8,
|
||||||
w, h, w,
|
w, h, w * 4,
|
||||||
free_pixels,
|
free_pixels,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (w != META_ICON_WIDTH || h != META_ICON_HEIGHT)
|
replace_icon (window, unscaled);
|
||||||
{
|
|
||||||
/* FIXME should keep aspect ratio, but for now assuming
|
|
||||||
* a square source icon
|
|
||||||
*/
|
|
||||||
window->icon = gdk_pixbuf_scale_simple (unscaled,
|
|
||||||
META_ICON_WIDTH,
|
|
||||||
META_ICON_HEIGHT,
|
|
||||||
GDK_INTERP_BILINEAR);
|
|
||||||
|
|
||||||
g_object_unref (G_OBJECT (unscaled));
|
g_object_unref (G_OBJECT (unscaled));
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
window->icon = unscaled;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
@ -3768,12 +3828,68 @@ update_icon (MetaWindow *window,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fallback to pixmap + mask */
|
/* Fallback to pixmap + mask */
|
||||||
/* FIXME well, I'm not sure how to deal with the mask */
|
|
||||||
/* FIXME for that matter, I don't know how we get the
|
if (window->icon_pixmap != None)
|
||||||
* icon pixmap as pixbuf without knowing if it's a bitmap,
|
{
|
||||||
* so we may be entirely hosed. I guess we can try to get it
|
GdkPixbuf *unscaled;
|
||||||
* with a nice error trap.
|
int w, h;
|
||||||
*/
|
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
|
||||||
|
get_pixmap_geometry (window->display, window->icon_pixmap,
|
||||||
|
&w, &h, NULL);
|
||||||
|
|
||||||
|
/* FIXME get mask and copy it to alpha channel of pixmap */
|
||||||
|
|
||||||
|
unscaled = meta_gdk_pixbuf_get_from_pixmap (NULL,
|
||||||
|
window->icon_pixmap,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
w, h);
|
||||||
|
|
||||||
|
meta_error_trap_pop (window->display);
|
||||||
|
|
||||||
|
if (unscaled)
|
||||||
|
{
|
||||||
|
meta_verbose ("Used pixmap icon\n");
|
||||||
|
replace_icon (window, unscaled);
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_verbose ("Failed to get pixmap icon as pixbuf\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->kwm_pixmap != None)
|
||||||
|
{
|
||||||
|
GdkPixbuf *unscaled;
|
||||||
|
int w, h;
|
||||||
|
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
|
||||||
|
get_pixmap_geometry (window->display, window->kwm_pixmap,
|
||||||
|
&w, &h, NULL);
|
||||||
|
|
||||||
|
/* FIXME get mask and copy it to alpha channel of pixmap */
|
||||||
|
|
||||||
|
unscaled = meta_gdk_pixbuf_get_from_pixmap (NULL,
|
||||||
|
window->kwm_pixmap,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
w, h);
|
||||||
|
|
||||||
|
meta_error_trap_pop (window->display);
|
||||||
|
|
||||||
|
if (unscaled)
|
||||||
|
{
|
||||||
|
meta_verbose ("Used kwm icon\n");
|
||||||
|
replace_icon (window, unscaled);
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_verbose ("Failed to get kwm icon as pixbuf\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Fallback to a default icon */
|
/* Fallback to a default icon */
|
||||||
if (window->icon == NULL)
|
if (window->icon == NULL)
|
||||||
@ -3782,6 +3898,45 @@ update_icon (MetaWindow *window,
|
|||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
update_kwm_icon (MetaWindow *window)
|
||||||
|
{
|
||||||
|
Atom type;
|
||||||
|
int format;
|
||||||
|
gulong nitems;
|
||||||
|
gulong bytes_after;
|
||||||
|
Pixmap *icons;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
window->kwm_pixmap = None;
|
||||||
|
window->kwm_mask = None;
|
||||||
|
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
icons = NULL;
|
||||||
|
XGetWindowProperty (window->display->xdisplay, window->xwindow,
|
||||||
|
window->display->atom_kwm_win_icon,
|
||||||
|
0, G_MAXLONG,
|
||||||
|
False, window->display->atom_kwm_win_icon,
|
||||||
|
&type, &format, &nitems,
|
||||||
|
&bytes_after, (guchar **)&icons);
|
||||||
|
|
||||||
|
result = meta_error_trap_pop (window->display);
|
||||||
|
if (result != Success)
|
||||||
|
return None;
|
||||||
|
|
||||||
|
if (type != window->display->atom_kwm_win_icon)
|
||||||
|
return None;
|
||||||
|
|
||||||
|
window->kwm_pixmap = icons[0];
|
||||||
|
window->kwm_mask = icons[1];
|
||||||
|
|
||||||
|
meta_verbose ("Found KWM_WIN_ICON 0x%lx\n", window->kwm_pixmap);
|
||||||
|
|
||||||
|
XFree (icons);
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
recalc_window_type (MetaWindow *window)
|
recalc_window_type (MetaWindow *window)
|
||||||
{
|
{
|
||||||
|
@ -77,6 +77,12 @@ struct _MetaWindow
|
|||||||
Pixmap icon_pixmap;
|
Pixmap icon_pixmap;
|
||||||
Pixmap icon_mask;
|
Pixmap icon_mask;
|
||||||
|
|
||||||
|
/* these are legacy and should die once we have _NET_WM_ICON in
|
||||||
|
* most apps
|
||||||
|
*/
|
||||||
|
Pixmap kwm_pixmap;
|
||||||
|
Pixmap kwm_mask;
|
||||||
|
|
||||||
/* Whether ->icon is from NET_WM_ICON instead of pixmap */
|
/* Whether ->icon is from NET_WM_ICON instead of pixmap */
|
||||||
guint using_rgb_icon : 1;
|
guint using_rgb_icon : 1;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user