The better patch.
--- a/src/wmframe.cc 2009-10-28 17:09:16.000000000 +0300 +++ b/src/wmframe.cc 2009-10-28 21:10:00.000000000 +0300 @@ -2397,28 +2397,42 @@ ref<YIcon> oldFrameIcon = fFrameIcon; if (client()->getNetWMIcon(&count, &elem)) { - ref<YImage> icons[4]; - int sizes[] = { YIcon::smallSize(), YIcon::largeSize(), YIcon::hugeSize() }; - - // find icons that match Small-/Large-/HugeIconSize, icons[3] is - // fallback if none matches - for (long *e = elem; e - count < elem; e += 2 + e[0] * e[1]) { - int i = 0; - for (; i < 3; i++) - if (e[0] == sizes[i] && e[0] == e[1]) - break; - if (icons[i] == null) - icons[i] = YImage::createFromIconProperty(e + 2, e[0], e[1]); - } - - // use the next larger existing icon to scale those that were missing - for (int i = 0; i < 3; i++) - if (icons[i] == null) - for (int j = i + 1; j < 4; j++) - if (icons[j] != null) { - icons[i] = icons[j]->scale(sizes[i], sizes[i]); - break; - } + ref<YImage> icons[3], largestIcon; + int sizes[] = { YIcon::smallSize(), YIcon::largeSize(), YIcon::hugeSize()}; + long *largestIconOffset = elem; + int largestIconSize = 0; + + // Find icons that match Small-/Large-/HugeIconSize and search + // for the largest icon from NET_WM_ICON set. + for (long *e = elem; e - count < elem && e[0] > 0 && e[1] > 0; + e += 2 + e[0] * e[1]) { + + if (e[0] > largestIconSize && e[0] == e[1]) { + largestIconOffset = e; + largestIconSize = e[0]; + } + + // It's possible when huge=large=small, so we must go + // through all sizes[] + for (int i = 0; i < 3; i++) { + if (e[0] == sizes[i] && e[0] == e[1] && icons[i] == null) + icons[i] = YImage::createFromIconProperty(e + 2, e[0], e[1]); + } + } + + // create the largest icon + if (largestIconSize > 0) + largestIcon = + YImage::createFromIconProperty(largestIconOffset + 2, + largestIconSize, + largestIconSize); + + // create the missing icons by downscaling the largest icon + // Q: Do we need to upscale the largest icon up to missing icon size? + if (largestIcon != null) + for (int i = 0; i < 3; i++) + if (icons[i] == null && sizes[i] < largestIconSize) + icons[i] = largestIcon->scale(sizes[i], sizes[i]); fFrameIcon.init(new YIcon(icons[0], icons[1], icons[2])); XFree(elem);