]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
watch for windows without frames, they can be in the transient order before they...
[chaz/openbox] / openbox / client.c
index 2fcbd003b481f72e48628557247a33ea67051e34..c475fba309054982c873a1942fe258c556a75bbb 100644 (file)
@@ -1,4 +1,5 @@
 #include "client.h"
+#include "startup.h"
 #include "screen.h"
 #include "moveresize.h"
 #include "prop.h"
@@ -26,9 +27,6 @@
 GList      *client_list      = NULL;
 GHashTable *client_map       = NULL;
 
-static Window *client_startup_stack_order = NULL;
-static guint  client_startup_stack_size = 0;
-
 static void client_get_all(Client *self);
 static void client_toggle_border(Client *self, gboolean show);
 static void client_get_area(Client *self);
@@ -53,11 +51,6 @@ void client_startup()
     client_map = g_hash_table_new((GHashFunc)map_hash,
                                  (GEqualFunc)map_key_comp);
 
-    /* save the stacking order on startup! */
-    PROP_GETA32(ob_root, net_client_list_stacking, window,
-                (guint32**)&client_startup_stack_order,
-                &client_startup_stack_size);
-
     client_set_list();
 }
 
@@ -95,6 +88,7 @@ void client_manage_all()
     Window w, *children;
     XWMHints *wmhints;
     XWindowAttributes attrib;
+    Client *active;
 
     XQueryTree(ob_display, ob_root, &w, &w, &children, &nchild);
 
@@ -130,19 +124,22 @@ void client_manage_all()
        why with stacking_lower? Why, because then windows who aren't in the
        stacking list are on the top where you can see them instead of buried
        at the bottom! */
-    for (i = client_startup_stack_size; i > 0; --i) {
+    for (i = startup_stack_size; i > 0; --i) {
         Client *c;
 
-        w = client_startup_stack_order[i-1];
+        w = startup_stack_order[i-1];
         c = g_hash_table_lookup(client_map, &w);
         if (c) stacking_lower(c);
     }
-    g_free(client_startup_stack_order);
-    client_startup_stack_order = NULL;
-    client_startup_stack_size = 0;
+    g_free(startup_stack_order);
+    startup_stack_order = NULL;
+    startup_stack_size = 0;
 
-    if (config_focus_new)
-        focus_fallback(Fallback_NoFocus);
+    if (config_focus_new) {
+        active = g_hash_table_lookup(client_map, &startup_active);
+        if (!active || !client_focus(active))
+            focus_fallback(Fallback_NoFocus);
+    }
 }
 
 void client_manage(Window window)
@@ -152,7 +149,6 @@ void client_manage(Window window)
     XWindowAttributes attrib;
     XSetWindowAttributes attrib_set;
 /*    XWMHints *wmhint; */
-    guint i;
 
     grab_server(TRUE);
 
@@ -222,13 +218,7 @@ void client_manage(Window window)
     g_hash_table_insert(client_map, &self->window, self);
 
     /* update the focus lists */
-    if (self->desktop == DESKTOP_ALL) {
-        for (i = 0; i < screen_num_desktops; ++i)
-            focus_order[i] = g_list_insert(focus_order[i], self, 1);
-    } else {
-        i = self->desktop;
-        focus_order[i] = g_list_insert(focus_order[i], self, 1);
-    }
+    focus_order_add_new(self);
 
     stacking_raise(self);
 
@@ -300,7 +290,6 @@ void client_unmanage_all()
 
 void client_unmanage(Client *self)
 {
-    guint i;
     int j;
     GSList *it;
 
@@ -322,13 +311,7 @@ void client_unmanage(Client *self)
     g_hash_table_remove(client_map, &self->window);
 
     /* update the focus lists */
-    if (self->desktop == DESKTOP_ALL) {
-        for (i = 0; i < screen_num_desktops; ++i)
-            focus_order[i] = g_list_remove(focus_order[i], self);
-    } else {
-        i = self->desktop;
-        focus_order[i] = g_list_remove(focus_order[i], self);
-    }
+    focus_order_remove(self);
 
     /* once the client is out of the list, update the struts to remove it's
        influence */
@@ -1750,6 +1733,9 @@ void client_iconify(Client *self, gboolean iconic, gboolean curdesk)
        /* we unmap the client itself so that we can get MapRequest events,
           and because the ICCCM tells us to! */
        XUnmapWindow(ob_display, self->window);
+
+        /* update the focus lists.. iconic windows go to the bottom */
+        focus_order_to_bottom(self);
     } else {
        if (curdesk)
            client_set_desktop(self, screen_desktop, FALSE);
@@ -1918,7 +1904,7 @@ void client_kill(Client *self)
 
 void client_set_desktop(Client *self, guint target, gboolean donthide)
 {
-    guint old, i;
+    guint old;
 
     if (target == self->desktop) return;
   
@@ -1926,6 +1912,9 @@ void client_set_desktop(Client *self, guint target, gboolean donthide)
 
     g_assert(target < screen_num_desktops || target == DESKTOP_ALL);
 
+    /* remove from the old desktop(s) */
+    focus_order_remove(self);
+
     old = self->desktop;
     self->desktop = target;
     PROP_SET32(self->window, net_wm_desktop, cardinal, target);
@@ -1939,25 +1928,11 @@ void client_set_desktop(Client *self, guint target, gboolean donthide)
         stacking_raise(self);
     screen_update_struts();
 
-    /* update the focus lists */
-    if (old == DESKTOP_ALL) {
-        for (i = 0; i < screen_num_desktops; ++i)
-            focus_order[i] = g_list_remove(focus_order[i], self);
-    } else
-        focus_order[old] = g_list_remove(focus_order[old], self);
-    if (target == DESKTOP_ALL) {
-        for (i = 0; i < screen_num_desktops; ++i) {
-            if (config_focus_new)
-                focus_order[i] = g_list_prepend(focus_order[i], self);
-            else
-                focus_order[i] = g_list_append(focus_order[i], self);
-        }
-    } else {
-        if (config_focus_new)
-            focus_order[target] = g_list_prepend(focus_order[target], self);
-        else
-            focus_order[target] = g_list_append(focus_order[target], self);
-    }
+    /* add to the new desktop(s) */
+    if (config_focus_new)
+        focus_order_to_top(self);
+    else
+        focus_order_to_bottom(self);
 
     dispatch_client(Event_Client_Desktop, self, target, old);
 }
@@ -2144,38 +2119,23 @@ Client *client_focus_target(Client *self)
     return self;
 }
 
-gboolean client_focusable(Client *self)
-{
-    /* won't try focus if the client doesn't want it, or if the window isn't
-       visible on the screen */
-    return self->frame->visible &&
-        (self->can_focus || self->focus_notify);
-}
-
 gboolean client_focus(Client *self)
 {
     XEvent ev;
-    guint i;
 
     /* choose the correct target */
     self = client_focus_target(self);
 
     if (self->desktop != DESKTOP_ALL && self->desktop != screen_desktop) {
         /* update the focus lists */
-        if (self->desktop == DESKTOP_ALL) {
-            for (i = 0; i < screen_num_desktops; ++i) {
-                focus_order[i] = g_list_remove(focus_order[i], self);
-                focus_order[i] = g_list_prepend(focus_order[i], self);
-            }
-        } else {
-            i = self->desktop;
-            focus_order[i] = g_list_remove(focus_order[i], self);
-            focus_order[i] = g_list_prepend(focus_order[i], self);
-        }
+        focus_order_to_top(self);
         return FALSE;
     }
 
-    if (!client_focusable(self))
+    if (!((self->can_focus || self->focus_notify) &&
+          (self->desktop == screen_desktop ||
+           self->desktop == DESKTOP_ALL) &&
+          !self->iconic))
        return FALSE;
 
     /* do a check to see if the window has already been unmapped or destroyed
This page took 0.027133 seconds and 4 git commands to generate.