diff -urN WindowMaker-0.91.0/src/wmspec.c WindowMaker-0.91.0.patch/src/wmspec.c --- WindowMaker-0.91.0/src/wmspec.c 2004-10-24 21:36:15.000000000 +0200 +++ WindowMaker-0.91.0.patch/src/wmspec.c 2005-01-12 23:31:41.833101648 +0100 @@ -369,57 +369,108 @@ return -1; } +/* + * Find the best icon to be used by Window Maker for appicon/miniwindows. + * Currently the algorithm is to take the image with the size closest + * to icon_size x icon_size, but never bigger than that. + * + * This algorithm is very poorly implemented and needs to be redone (it can + * easily select images with very large widths and very small heights over + * square images, if the area of the former is closer to the desired one). + * + * The logic can also be changed to accept bigger images and scale them down. + */ +static CARD32* +findBestIcon(CARD32 *data, unsigned long items) +{ + long size, wanted, d, distance; + unsigned long i; + CARD32 *icon; + + /* better use only 75% of icon_size. For 64x64 this means 48x48 + * This leaves room around the icon for the miniwindow title and + * results in better overall aesthetics -Dan */ + wanted = wPreferences.icon_size * wPreferences.icon_size; + + for (icon=NULL, distance=LONG_MAX, i=0L; i=0 && d<=distance && (i+size+2)<=items) { + distance = d; + icon = &data[i]; + } + i += size+2; + } + + return icon; +} + + +static RImage* +makeRImageFromARGBData(CARD32 *data) +{ + int size, width, height, i; + RImage *image; + unsigned char *imgdata; + CARD32 pixel; + + width = data[0]; + height = data[1]; + size = width * height; + + if (size == 0) + return NULL; + + image = RCreateImage(width, height, True); + + for (imgdata=image->data, i=2; i> 24) & 0xff; /* A */ + imgdata[0] = (pixel >> 16) & 0xff; /* R */ + imgdata[1] = (pixel >> 8) & 0xff; /* G */ + imgdata[2] = (pixel >> 0) & 0xff; /* B */ + } + + return image; +} + static void updateIconImage(WScreen *scr, WWindow *wwin) { - Atom actual_type_return; - int actual_format_return; - unsigned long nitems_return, bytes_after_return; - unsigned char *prop_return; - int rc = XGetWindowProperty(dpy, wwin->client_win, net_wm_icon, 0, ~0, False, - XA_CARDINAL, &actual_type_return, &actual_format_return, - &nitems_return, &bytes_after_return, &prop_return); - - if (rc==Success && prop_return) { - unsigned int *data = (unsigned int *)prop_return; - unsigned int pos = 0, len = 0; - unsigned int best_pos = 0, best_tmp = ~0; - extern WPreferences wPreferences; - unsigned int pref_size = wPreferences.icon_size; - unsigned int pref_sq = pref_size*pref_size; - char *src, *dst; - RImage *new_rimage; - - do { - len = data[pos+0]*data[pos+1]; - unsigned int tmp = pref_sq-len; - if (tmp < best_tmp && tmp > 0) { - best_tmp = tmp; - best_pos = pos; - } - pos += 2+len; - } while (pos < nitems_return && len != 0); + CARD32 *property, *data; + unsigned long items, rest; + Atom type; + int format; + RImage *image; + + if (XGetWindowProperty(dpy, wwin->client_win, net_wm_icon, 0L, LONG_MAX, + False, XA_CARDINAL, &type, &format, &items, &rest, + (unsigned char**)&property)!=Success || !property) { + return; + } - new_rimage = RCreateImage(data[best_pos+0], data[best_pos+1], True); - len = data[best_pos+0] * data[best_pos+1]; - src = (char*)&data[best_pos+2]; - dst = new_rimage->data; - for (pos=0; posnet_icon_image) RReleaseImage(wwin->net_icon_image); - wwin->net_icon_image = new_rimage; + wwin->net_icon_image = image; } - - XFree(prop_return); - } + XFree(property); }