summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDana Jansens <danakj@orodu.net>2008-01-27 03:14:35 -0500
committerDana Jansens <danakj@orodu.net>2008-01-27 03:14:35 -0500
commitee0477d167a3b87618b82d1080fd37e4403e6d2e (patch)
treeff12a649c93d1def5d32e61a6147615eee25e430
parent6be65a7ddd453bded890a90bb5c0b84b2a89c65a (diff)
only store icons for windows that are 64px or smaller, as we don't have need for any bigger icons at this time. unless they only provide icons bigger than that, then just store one of them (the smallest)
-rw-r--r--openbox/client.c55
1 files changed, 46 insertions, 9 deletions
diff --git a/openbox/client.c b/openbox/client.c
index 6adaa059..e5e25567 100644
--- a/openbox/client.c
+++ b/openbox/client.c
@@ -2067,11 +2067,17 @@ void client_update_strut(ObClient *self)
}
}
+/* Avoid storing icons above this size if possible */
+#define AVOID_ABOVE 64
+
void client_update_icons(ObClient *self)
{
guint num;
guint32 *data;
guint w, h, i, j;
+ guint num_seen; /* number of icons present */
+ guint num_small_seen; /* number of icons small enough present */
+ guint smallest, smallest_area;
for (i = 0; i < self->nicons; ++i)
g_free(self->icons[i].data);
@@ -2082,25 +2088,54 @@ void client_update_icons(ObClient *self)
if (PROP_GETA32(self->window, net_wm_icon, cardinal, &data, &num)) {
/* figure out how many valid icons are in here */
i = 0;
- while (num - i > 2) {
- w = data[i++];
- h = data[i++];
- i += w * h;
- if (i > num || w*h == 0) break;
- ++self->nicons;
- }
+ num_seen = num_small_seen = 0;
+ smallest = smallest_area = 0;
+ if (num > 2)
+ while (i < num) {
+ w = data[i++];
+ h = data[i++];
+ i += w * h;
+ /* watch for it being too small for the specified size, or for
+ zero sized icons. */
+ if (i > num || w == 0 || h == 0) break;
+
+ if (!smallest_area || w*h < smallest_area) {
+ smallest = num_seen;
+ smallest_area = w*h;
+ }
+ ++num_seen;
+ if (w <= AVOID_ABOVE && h <= AVOID_ABOVE)
+ ++num_small_seen;
+ }
+ if (num_small_seen > 0)
+ self->nicons = num_small_seen;
+ else if (num_seen)
+ self->nicons = 1;
self->icons = g_new(ObClientIcon, self->nicons);
/* store the icons */
i = 0;
- for (j = 0; j < self->nicons; ++j) {
+ for (j = 0; j < self->nicons;) {
guint x, y, t;
w = self->icons[j].width = data[i++];
h = self->icons[j].height = data[i++];
- if (w*h == 0) continue;
+ /* if there are some icons smaller than the threshold, we're
+ skipping all the ones above */
+ if (num_small_seen > 0) {
+ if (w > AVOID_ABOVE || h > AVOID_ABOVE) {
+ i += w*h;
+ continue;
+ }
+ }
+ /* if there were no icons smaller than the threshold, then we are
+ only taking the smallest available one we saw */
+ else if (j != smallest) {
+ i += w*h;
+ continue;
+ }
self->icons[j].data = g_new(RrPixel32, w * h);
for (x = 0, y = 0, t = 0; t < w * h; ++t, ++x, ++i) {
@@ -2115,6 +2150,8 @@ void client_update_icons(ObClient *self)
(((data[i] >> 0) & 0xff) << RrDefaultBlueOffset);
}
g_assert(i <= num);
+
+ ++j;
}
g_free(data);