we support _NET_WM_ICON
2001-08-19 Havoc Pennington <hp@pobox.com> * src/screen.c (set_supported_hint): we support _NET_WM_ICON * src/wm-tester/main.c: add stuff to test _NET_WM_ICON (but it doesn't work, so it isn't tested yet) * src/window.c (update_icon): read _NET_WM_ICON * src/screen.c (meta_screen_new): set the WM_ICON_SIZE hint * src/tabpopup.c (meta_ui_tab_popup_select): remove assertion * src/window.c (meta_window_get_icon_geometry): fix obscure memleak
This commit is contained in:
parent
78a68f3e10
commit
04e09d4c56
12 changed files with 460 additions and 30 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
2001-08-19 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* src/screen.c (set_supported_hint): we support _NET_WM_ICON
|
||||
|
||||
* src/wm-tester/main.c: add stuff to test _NET_WM_ICON
|
||||
(but it doesn't work, so it isn't tested yet)
|
||||
|
||||
* src/window.c (update_icon): read _NET_WM_ICON
|
||||
|
||||
* src/screen.c (meta_screen_new): set the WM_ICON_SIZE hint
|
||||
|
||||
* src/tabpopup.c (meta_ui_tab_popup_select): remove assertion
|
||||
|
||||
* src/window.c (meta_window_get_icon_geometry): fix obscure
|
||||
memleak
|
||||
|
||||
2001-08-19 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* src/display.c (meta_display_grab_window_buttons): remove XSync,
|
||||
|
|
|
@ -132,7 +132,8 @@ meta_display_open (const char *name)
|
|||
"_NET_WM_ICON_NAME",
|
||||
"_NET_WM_ICON",
|
||||
"_NET_WM_ICON_GEOMETRY",
|
||||
"UTF8_STRING"
|
||||
"UTF8_STRING",
|
||||
"WM_ICON_SIZE"
|
||||
};
|
||||
Atom atoms[G_N_ELEMENTS(atom_names)];
|
||||
|
||||
|
@ -216,6 +217,7 @@ meta_display_open (const char *name)
|
|||
display->atom_net_wm_icon = atoms[37];
|
||||
display->atom_net_wm_icon_geometry = atoms[38];
|
||||
display->atom_utf8_string = atoms[39];
|
||||
display->atom_wm_icon_size = atoms[40];
|
||||
|
||||
/* Offscreen unmapped window used for _NET_SUPPORTING_WM_CHECK,
|
||||
* created in screen_new
|
||||
|
|
|
@ -97,6 +97,7 @@ struct _MetaDisplay
|
|||
Atom atom_net_wm_icon;
|
||||
Atom atom_net_wm_icon_geometry;
|
||||
Atom atom_utf8_string;
|
||||
Atom atom_wm_icon_size;
|
||||
|
||||
/* This is the actual window from focus events,
|
||||
* not the one we last set
|
||||
|
|
|
@ -22,6 +22,10 @@ if test -n "$EVIL_TEST"; then
|
|||
TEST_CLIENT='./wm-tester/wm-tester --evil'
|
||||
fi
|
||||
|
||||
if test -n "$ICON_TEST"; then
|
||||
TEST_CLIENT='./wm-tester/wm-tester --icon-windows'
|
||||
fi
|
||||
|
||||
if test -z "$ONLY_WM"; then
|
||||
Xnest -ac :1 -scrns $SCREENS -geometry 640x480 -bw 15 &
|
||||
## usleep 800000
|
||||
|
|
28
src/screen.c
28
src/screen.c
|
@ -72,7 +72,7 @@ set_wm_check_hint (MetaScreen *screen)
|
|||
static int
|
||||
set_supported_hint (MetaScreen *screen)
|
||||
{
|
||||
#define N_SUPPORTED 21
|
||||
#define N_SUPPORTED 22
|
||||
#define N_WIN_SUPPORTED 1
|
||||
Atom atoms[N_SUPPORTED];
|
||||
|
||||
|
@ -97,6 +97,7 @@ set_supported_hint (MetaScreen *screen)
|
|||
atoms[18] = screen->display->atom_net_client_list_stacking;
|
||||
atoms[19] = screen->display->atom_net_wm_state_skip_taskbar;
|
||||
atoms[20] = screen->display->atom_net_wm_state_skip_pager;
|
||||
atoms[21] = screen->display->atom_net_wm_icon;
|
||||
|
||||
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||
screen->display->atom_net_wm_supported,
|
||||
|
@ -115,6 +116,29 @@ set_supported_hint (MetaScreen *screen)
|
|||
#undef N_SUPPORTED
|
||||
}
|
||||
|
||||
static int
|
||||
set_wm_icon_size_hint (MetaScreen *screen)
|
||||
{
|
||||
#define N_VALS 6
|
||||
gulong vals[N_VALS];
|
||||
|
||||
/* min width, min height, max w, max h, width inc, height inc */
|
||||
vals[0] = META_ICON_WIDTH;
|
||||
vals[1] = META_ICON_HEIGHT;
|
||||
vals[2] = META_ICON_WIDTH;
|
||||
vals[3] = META_ICON_HEIGHT;
|
||||
vals[4] = 0;
|
||||
vals[5] = 0;
|
||||
|
||||
XChangeProperty (screen->display->xdisplay, screen->xroot,
|
||||
screen->display->atom_wm_icon_size,
|
||||
XA_CARDINAL,
|
||||
32, PropModeReplace, (guchar*) vals, N_VALS);
|
||||
|
||||
return Success;
|
||||
#undef N_VALS
|
||||
}
|
||||
|
||||
MetaScreen*
|
||||
meta_screen_new (MetaDisplay *display,
|
||||
int number)
|
||||
|
@ -177,6 +201,8 @@ meta_screen_new (MetaDisplay *display,
|
|||
display->leader_window = XCreateSimpleWindow (display->xdisplay,
|
||||
screen->xroot,
|
||||
-100, -100, 1, 1, 0, 0, 0);
|
||||
|
||||
set_wm_icon_size_hint (screen);
|
||||
|
||||
set_supported_hint (screen);
|
||||
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
#include <X11/Xutil.h>
|
||||
#include "ui.h"
|
||||
|
||||
|
||||
/* should investigate changing these to whatever most apps use */
|
||||
#define META_ICON_WIDTH 32
|
||||
#define META_ICON_HEIGHT 32
|
||||
|
||||
typedef void (* MetaScreenWindowFunc) (MetaScreen *screen, MetaWindow *window,
|
||||
gpointer user_data);
|
||||
|
||||
|
|
|
@ -287,6 +287,4 @@ meta_ui_tab_popup_select (MetaTabPopup *popup,
|
|||
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
meta_bug ("Selected nonexistent entry 0x%lx in tab popup\n", xwindow);
|
||||
}
|
||||
|
|
35
src/ui.c
35
src/ui.c
|
@ -333,6 +333,41 @@ meta_gdk_pixbuf_get_from_window (GdkPixbuf *dest,
|
|||
return retval;
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
meta_gdk_pixbuf_get_from_pixmap (GdkPixbuf *dest,
|
||||
Pixmap xpixmap,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
GdkDrawable *drawable;
|
||||
GdkPixbuf *retval;
|
||||
|
||||
retval = NULL;
|
||||
|
||||
drawable = gdk_xid_table_lookup (xpixmap);
|
||||
|
||||
if (drawable)
|
||||
g_object_ref (G_OBJECT (drawable));
|
||||
else
|
||||
drawable = gdk_pixmap_foreign_new (xpixmap);
|
||||
|
||||
retval = gdk_pixbuf_get_from_drawable (dest,
|
||||
drawable,
|
||||
/* We assume root window cmap */
|
||||
gdk_colormap_get_system (),
|
||||
src_x, src_y,
|
||||
dest_x, dest_y,
|
||||
width, height);
|
||||
|
||||
g_object_unref (G_OBJECT (drawable));
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void
|
||||
meta_ui_push_delay_exposes (MetaUI *ui)
|
||||
{
|
||||
|
|
9
src/ui.h
9
src/ui.h
|
@ -110,6 +110,15 @@ GdkPixbuf* meta_gdk_pixbuf_get_from_window (GdkPixbuf *dest,
|
|||
int width,
|
||||
int height);
|
||||
|
||||
GdkPixbuf* meta_gdk_pixbuf_get_from_pixmap (GdkPixbuf *dest,
|
||||
Pixmap xpixmap,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
/* Used when we have a server grab and draw all over everything,
|
||||
* then we need to handle exposes after doing that, instead of
|
||||
* during it
|
||||
|
|
298
src/window.c
298
src/window.c
|
@ -59,7 +59,8 @@ static int update_role (MetaWindow *window);
|
|||
static int update_net_wm_type (MetaWindow *window);
|
||||
static int update_initial_workspace (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);
|
||||
static void recalc_window_type (MetaWindow *window);
|
||||
static void recalc_window_features (MetaWindow *window);
|
||||
static int set_wm_state (MetaWindow *window,
|
||||
|
@ -317,6 +318,8 @@ meta_window_new (MetaDisplay *display, Window xwindow,
|
|||
|
||||
window->icon_pixmap = None;
|
||||
window->icon_mask = None;
|
||||
|
||||
window->using_rgb_icon = FALSE;
|
||||
|
||||
window->type = META_WINDOW_NORMAL;
|
||||
window->type_atom = None;
|
||||
|
@ -328,7 +331,7 @@ meta_window_new (MetaDisplay *display, Window xwindow,
|
|||
|
||||
update_size_hints (window);
|
||||
update_title (window);
|
||||
update_protocols (window);
|
||||
update_protocols (window);
|
||||
update_wm_hints (window);
|
||||
update_net_wm_state (window);
|
||||
update_mwm_hints (window);
|
||||
|
@ -339,7 +342,8 @@ meta_window_new (MetaDisplay *display, Window xwindow,
|
|||
update_net_wm_type (window);
|
||||
update_initial_workspace (window);
|
||||
update_icon_name (window);
|
||||
update_icon (window);
|
||||
/* should come after wm_hints */
|
||||
update_icon (window, TRUE);
|
||||
|
||||
if (!window->mapped &&
|
||||
(window->size_hints.flags & PPosition) == 0 &&
|
||||
|
@ -2331,7 +2335,6 @@ process_property_notify (MetaWindow *window,
|
|||
meta_verbose ("Property notify on %s for WM_HINTS\n", window->desc);
|
||||
|
||||
update_wm_hints (window);
|
||||
update_icon (window);
|
||||
|
||||
meta_window_queue_move_resize (window);
|
||||
}
|
||||
|
@ -2395,7 +2398,7 @@ process_property_notify (MetaWindow *window,
|
|||
else if (event->atom == window->display->atom_net_wm_icon)
|
||||
{
|
||||
meta_verbose ("Property notify on %s for NET_WM_ICON\n", window->desc);
|
||||
update_icon (window);
|
||||
update_icon (window, TRUE);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -2742,7 +2745,12 @@ static int
|
|||
update_wm_hints (MetaWindow *window)
|
||||
{
|
||||
XWMHints *hints;
|
||||
Pixmap old_icon;
|
||||
Pixmap old_mask;
|
||||
|
||||
old_icon = window->icon_pixmap;
|
||||
old_mask = window->icon_mask;
|
||||
|
||||
/* Fill in defaults */
|
||||
window->input = FALSE;
|
||||
window->initially_iconic = FALSE;
|
||||
|
@ -2769,6 +2777,14 @@ update_wm_hints (MetaWindow *window)
|
|||
|
||||
if (hints->flags & IconMaskHint)
|
||||
window->icon_mask = hints->icon_mask;
|
||||
|
||||
if (window->icon_pixmap != old_icon ||
|
||||
window->icon_mask != old_mask)
|
||||
{
|
||||
meta_verbose ("Icon pixmap or mask changed in WM_HINTS for %s\n",
|
||||
window->desc);
|
||||
update_icon (window, FALSE);
|
||||
}
|
||||
|
||||
meta_verbose ("Read WM_HINTS input: %d iconic: %d group leader: 0x%ld\n",
|
||||
window->input, window->initially_iconic,
|
||||
|
@ -3025,8 +3041,14 @@ meta_window_get_icon_geometry (MetaWindow *window,
|
|||
|
||||
result = meta_error_trap_pop (window->display);
|
||||
|
||||
if (result != Success || type != XA_CARDINAL || nitems != 4)
|
||||
return FALSE;
|
||||
if (result != Success || type != XA_CARDINAL)
|
||||
return FALSE;
|
||||
|
||||
if (nitems != 4)
|
||||
{
|
||||
XFree (geometry);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (rect)
|
||||
{
|
||||
|
@ -3442,7 +3464,7 @@ update_icon_name (MetaWindow *window)
|
|||
text.format == 8 &&
|
||||
g_utf8_validate (text.value, text.nitems, NULL))
|
||||
{
|
||||
meta_verbose ("Using _NET_WM_ICON_NAME for new title of %s: '%s'\n",
|
||||
meta_verbose ("Using _NET_WM_ICON_NAME for new icon name of %s: '%s'\n",
|
||||
window->desc, text.value);
|
||||
|
||||
window->icon_name = g_strdup (text.value);
|
||||
|
@ -3498,26 +3520,266 @@ update_icon_name (MetaWindow *window)
|
|||
return meta_error_trap_pop (window->display);
|
||||
}
|
||||
|
||||
static int
|
||||
update_icon (MetaWindow *window)
|
||||
{
|
||||
meta_error_trap_push (window->display);
|
||||
static gboolean
|
||||
find_best_size (gulong *data,
|
||||
gulong nitems,
|
||||
int *width,
|
||||
int *height,
|
||||
gulong **start)
|
||||
{
|
||||
int best_w;
|
||||
int best_h;
|
||||
gulong *best_start;
|
||||
|
||||
#if 0
|
||||
best_w = 0;
|
||||
best_h = 0;
|
||||
best_start = NULL;
|
||||
|
||||
while (nitems > 0)
|
||||
{
|
||||
int w, h;
|
||||
gboolean replace;
|
||||
|
||||
replace = FALSE;
|
||||
|
||||
if (nitems < 3)
|
||||
{
|
||||
meta_verbose ("_NET_WM_ICON contained too little data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
w = data[0];
|
||||
h = data[1];
|
||||
|
||||
if (nitems < ((w * h) + 2))
|
||||
{
|
||||
meta_verbose ("_NET_WM_ICON contained too little data\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (best_start == NULL)
|
||||
{
|
||||
replace = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* work with averages */
|
||||
const int ideal_size = META_ICON_WIDTH * META_ICON_HEIGHT;
|
||||
int best_size = (best_w + best_h) / 2;
|
||||
int this_size = (w + h) / 2;
|
||||
|
||||
/* larger than desired is always better than smaller */
|
||||
if (best_size < ideal_size &&
|
||||
this_size >= ideal_size)
|
||||
replace = TRUE;
|
||||
/* if we have too small, pick anything bigger */
|
||||
else if (best_size < ideal_size &&
|
||||
this_size > best_size)
|
||||
replace = TRUE;
|
||||
/* if we have too large, pick anything smaller
|
||||
* but still >= the ideal
|
||||
*/
|
||||
else if (best_size > ideal_size &&
|
||||
this_size >= ideal_size &&
|
||||
this_size < best_size)
|
||||
replace = TRUE;
|
||||
}
|
||||
|
||||
if (replace)
|
||||
{
|
||||
best_start = data + 2;
|
||||
best_w = w;
|
||||
best_h = h;
|
||||
}
|
||||
|
||||
nitems -= (w * h) + 2;
|
||||
}
|
||||
|
||||
if (best_start)
|
||||
{
|
||||
*start = best_start;
|
||||
*width = best_w;
|
||||
*height = best_h;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
read_rgb_icon (MetaWindow *window,
|
||||
int *width,
|
||||
int *height,
|
||||
guchar **pixdata)
|
||||
{
|
||||
Atom type;
|
||||
int format;
|
||||
gulong nitems;
|
||||
gulong bytes_after;
|
||||
int result;
|
||||
gulong *data; /* FIXME should be guint? */
|
||||
gulong *best;
|
||||
int i;
|
||||
int w, h;
|
||||
guchar *p;
|
||||
|
||||
if (sizeof (gulong) != 4)
|
||||
meta_warning ("%s: Whoops, I think this function may be broken on 64-bit\n",
|
||||
__FUNCTION__);
|
||||
|
||||
meta_error_trap_push (window->display);
|
||||
type = None;
|
||||
data = NULL;
|
||||
XGetWindowProperty (window->display->xdisplay,
|
||||
window->xwindow,
|
||||
window->display->atom_net_wm_icon,
|
||||
0, G_MAXLONG,
|
||||
False, XA_CARDINAL, &type, &format, &nitems,
|
||||
&bytes_after, ((guchar **)&data));
|
||||
|
||||
result = meta_error_trap_pop (window->display);
|
||||
|
||||
if (result != Success || type != XA_CARDINAL)
|
||||
{
|
||||
meta_verbose ("%s doesn't seem to set _NET_WM_ICON\n",
|
||||
window->desc);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!find_best_size (data, nitems, &w, &h, &best))
|
||||
{
|
||||
XFree (data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*width = w;
|
||||
*height = h;
|
||||
|
||||
*pixdata = g_new (guchar, w * h);
|
||||
p = *pixdata;
|
||||
|
||||
/* One could speed this up a lot. */
|
||||
i = 0;
|
||||
while (i < w * h)
|
||||
{
|
||||
guint argb;
|
||||
guint rgba;
|
||||
|
||||
argb = best[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;
|
||||
}
|
||||
|
||||
XFree (data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
clear_icon (MetaWindow *window)
|
||||
{
|
||||
if (window->icon)
|
||||
{
|
||||
g_object_unref (G_OBJECT (window->icon));
|
||||
window->icon = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
/* Fallback */
|
||||
static void
|
||||
free_pixels (guchar *pixels, gpointer data)
|
||||
{
|
||||
g_free (pixels);
|
||||
}
|
||||
|
||||
static int
|
||||
update_icon (MetaWindow *window,
|
||||
gboolean reload_rgb_icon)
|
||||
{
|
||||
|
||||
if (reload_rgb_icon)
|
||||
{
|
||||
guchar *pixdata;
|
||||
int w, h;
|
||||
|
||||
pixdata = NULL;
|
||||
|
||||
if (read_rgb_icon (window, &w, &h, &pixdata))
|
||||
{
|
||||
GdkPixbuf *unscaled;
|
||||
|
||||
meta_verbose ("successfully read RGBA icon fro _NET_WM_ICON\n");
|
||||
|
||||
window->using_rgb_icon = TRUE;
|
||||
|
||||
clear_icon (window);
|
||||
|
||||
unscaled = gdk_pixbuf_new_from_data (pixdata,
|
||||
GDK_COLORSPACE_RGB,
|
||||
TRUE,
|
||||
8,
|
||||
w, h, w,
|
||||
free_pixels,
|
||||
NULL);
|
||||
|
||||
if (w != META_ICON_WIDTH || h != 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);
|
||||
|
||||
g_object_unref (G_OBJECT (unscaled));
|
||||
}
|
||||
else
|
||||
{
|
||||
window->icon = unscaled;
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (window->using_rgb_icon)
|
||||
clear_icon (window);
|
||||
window->using_rgb_icon = FALSE;
|
||||
|
||||
/* We'll try to fall back to something else below. */
|
||||
}
|
||||
}
|
||||
else if (window->using_rgb_icon)
|
||||
{
|
||||
/* There's no way we want to use the fallbacks,
|
||||
* keep using this.
|
||||
*/
|
||||
return Success;
|
||||
}
|
||||
|
||||
/* 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
|
||||
* 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
|
||||
* with a nice error trap.
|
||||
*/
|
||||
|
||||
/* Fallback to a default icon */
|
||||
if (window->icon == NULL)
|
||||
window->icon = meta_ui_get_default_window_icon (window->screen->ui);
|
||||
|
||||
return meta_error_trap_pop (window->display);
|
||||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
11
src/window.h
11
src/window.h
|
@ -70,11 +70,14 @@ struct _MetaWindow
|
|||
Window xgroup_leader;
|
||||
Window xclient_leader;
|
||||
|
||||
Pixmap icon_pixmap;
|
||||
Pixmap icon_mask;
|
||||
|
||||
/* Initial workspace property */
|
||||
int initial_workspace;
|
||||
int initial_workspace;
|
||||
|
||||
Pixmap icon_pixmap;
|
||||
Pixmap icon_mask;
|
||||
|
||||
/* Whether ->icon is from NET_WM_ICON instead of pixmap */
|
||||
guint using_rgb_icon : 1;
|
||||
|
||||
/* Whether we're maximized */
|
||||
guint maximized : 1;
|
||||
|
|
|
@ -28,11 +28,12 @@
|
|||
#include <unistd.h>
|
||||
|
||||
static void set_up_the_evil (void);
|
||||
static void set_up_icon_windows (void);
|
||||
|
||||
static void
|
||||
usage (void)
|
||||
{
|
||||
g_print ("wm-tester [--evil]\n");
|
||||
g_print ("wm-tester [--evil] [--icon-windows]\n");
|
||||
exit (0);
|
||||
}
|
||||
|
||||
|
@ -41,10 +42,12 @@ main (int argc, char **argv)
|
|||
{
|
||||
int i;
|
||||
gboolean do_evil;
|
||||
|
||||
gboolean do_icon_windows;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
do_evil = FALSE;
|
||||
do_icon_windows = FALSE;
|
||||
|
||||
i = 1;
|
||||
while (i < argc)
|
||||
|
@ -57,6 +60,8 @@ main (int argc, char **argv)
|
|||
usage ();
|
||||
else if (strcmp (arg, "--evil") == 0)
|
||||
do_evil = TRUE;
|
||||
else if (strcmp (arg, "--icon-windows") == 0)
|
||||
do_icon_windows = TRUE;
|
||||
else
|
||||
usage ();
|
||||
|
||||
|
@ -64,12 +69,15 @@ main (int argc, char **argv)
|
|||
}
|
||||
|
||||
/* Be sure some option was provided */
|
||||
if (! (do_evil))
|
||||
if (! (do_evil || do_icon_windows))
|
||||
return 1;
|
||||
|
||||
if (do_evil)
|
||||
set_up_the_evil ();
|
||||
|
||||
|
||||
if (do_icon_windows)
|
||||
set_up_icon_windows ();
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
|
@ -156,3 +164,64 @@ set_up_the_evil (void)
|
|||
g_timeout_add (40, evil_timeout, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
set_up_icon_windows (void)
|
||||
{
|
||||
int i;
|
||||
int n_windows;
|
||||
|
||||
/* Create some windows */
|
||||
n_windows = 9;
|
||||
|
||||
i = 0;
|
||||
while (i < n_windows)
|
||||
{
|
||||
GtkWidget *w;
|
||||
GtkWidget *c;
|
||||
GList *icons;
|
||||
GdkPixbuf *pix;
|
||||
|
||||
w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
c = gtk_button_new_with_label ("Icon window");
|
||||
gtk_container_add (GTK_CONTAINER (w), c);
|
||||
|
||||
gtk_widget_realize (w);
|
||||
|
||||
icons = NULL;
|
||||
|
||||
pix = gtk_widget_render_icon (w,
|
||||
GTK_STOCK_SAVE,
|
||||
GTK_ICON_SIZE_LARGE_TOOLBAR,
|
||||
NULL);
|
||||
|
||||
icons = g_list_append (icons, pix);
|
||||
|
||||
if (i % 2)
|
||||
{
|
||||
pix = gtk_widget_render_icon (w,
|
||||
GTK_STOCK_SAVE,
|
||||
GTK_ICON_SIZE_DIALOG,
|
||||
NULL);
|
||||
icons = g_list_append (icons, pix);
|
||||
}
|
||||
|
||||
if (i % 3)
|
||||
{
|
||||
pix = gtk_widget_render_icon (w,
|
||||
GTK_STOCK_SAVE,
|
||||
GTK_ICON_SIZE_MENU,
|
||||
NULL);
|
||||
icons = g_list_append (icons, pix);
|
||||
}
|
||||
|
||||
if (!gdk_window_set_icon_list (w->window, icons))
|
||||
g_warning ("_NET_WM_ICON not supported?");
|
||||
|
||||
g_list_foreach (icons, (GFunc) g_object_unref, NULL);
|
||||
g_list_free (icons);
|
||||
|
||||
gtk_widget_show_all (w);
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue