]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
only store icons for windows that are 64px or smaller, as we don't have need for...
[chaz/openbox] / openbox / client.c
index c90c39bf7cceefa6cc658e38c828a0dd0d203189..e5e2556789281e662090133a78d39d1283378fd0 100644 (file)
@@ -24,6 +24,7 @@
 #include "xerror.h"
 #include "screen.h"
 #include "moveresize.h"
+#include "ping.h"
 #include "place.h"
 #include "prop.h"
 #include "extensions.h"
@@ -79,6 +80,10 @@ static void client_get_state(ObClient *self);
 static void client_get_shaped(ObClient *self);
 static void client_get_mwm_hints(ObClient *self);
 static void client_get_colormap(ObClient *self);
+static void client_set_desktop_recursive(ObClient *self,
+                                         guint target,
+                                         gboolean donthide,
+                                         gboolean dontraise);
 static void client_change_allowed_actions(ObClient *self);
 static void client_change_state(ObClient *self);
 static void client_change_wm_state(ObClient *self);
@@ -308,7 +313,7 @@ void client_manage(Window window)
     client_setup_decor_and_functions(self, FALSE);
 
     /* tell startup notification that this app started */
-    launch_time = sn_app_started(self->startup_id, self->class);
+    launch_time = sn_app_started(self->startup_id, self->class, self->name);
 
     /* do this after we have a frame.. it uses the frame to help determine the
        WM_STATE to apply. */
@@ -604,7 +609,10 @@ void client_manage(Window window)
 
     /* watch for when the application stops responding.  only do this for
        normal windows, i.e. windows which have titlebars and close buttons 
-       and things like that */
+       and things like that.
+       we don't need to stop pinging on unmanage, because it will be handled
+       automatically by the destroy callback!
+    */
     if (self->ping && client_normal(self))
         ping_start(self, client_ping_event);
 
@@ -689,10 +697,6 @@ void client_unmanage(ObClient *self)
     /* remove the window from our save set */
     XChangeSaveSet(ob_display, self->window, SetModeDelete);
 
-    /* stop pinging the window */
-    if (self->ping && client_normal(self))
-        ping_stop(self);
-
     /* update the focus lists */
     focus_order_remove(self);
     if (client_focused(self)) {
@@ -794,6 +798,7 @@ void client_unmanage(ObClient *self)
         g_free(self->icons[j].data);
     if (self->nicons > 0)
         g_free(self->icons);
+    g_free(self->startup_id);
     g_free(self->wm_command);
     g_free(self->title);
     g_free(self->icon_title);
@@ -1551,7 +1556,7 @@ void client_update_sync_request_counter(ObClient *self)
 }
 #endif
 
-void client_get_colormap(ObClient *self)
+static void client_get_colormap(ObClient *self)
 {
     XWindowAttributes wa;
 
@@ -2062,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);
@@ -2077,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) {
@@ -2110,6 +2150,8 @@ void client_update_icons(ObClient *self)
                     (((data[i] >> 0) & 0xff) << RrDefaultBlueOffset);
             }
             g_assert(i <= num);
+
+            ++j;
         }
 
         g_free(data);
@@ -2171,12 +2213,13 @@ void client_update_icon_geometry(ObClient *self)
 
     RECT_SET(self->icon_geometry, 0, 0, 0, 0);
 
-    if (PROP_GETA32(self->window, net_wm_icon_geometry, cardinal, &data, &num)
-        && num == 4)
+    if (PROP_GETA32(self->window, net_wm_icon_geometry, cardinal, &data, &num))
     {
-        /* don't let them set it with an area < 0 */
-        RECT_SET(self->icon_geometry, data[0], data[1],
-                 MAX(data[2],0), MAX(data[3],0));
+        if (num == 4)
+            /* don't let them set it with an area < 0 */
+            RECT_SET(self->icon_geometry, data[0], data[1],
+                     MAX(data[2],0), MAX(data[3],0));
+        g_free(data);
     }
 }
 
@@ -3276,10 +3319,10 @@ void client_hilite(ObClient *self, gboolean hilite)
     }
 }
 
-void client_set_desktop_recursive(ObClient *self,
-                                  guint target,
-                                  gboolean donthide,
-                                  gboolean dontraise)
+static void client_set_desktop_recursive(ObClient *self,
+                                         guint target,
+                                         gboolean donthide,
+                                         gboolean dontraise)
 {
     guint old;
     GSList *it;
This page took 0.025312 seconds and 4 git commands to generate.