]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
no separator at the start of the menu
[chaz/openbox] / openbox / client.c
index 5896ece0ffc7f58d6fe49b09f467a425cf04e9cf..c59baf96905d7d04036ed6b632b7b98b91ba0b7f 100644 (file)
@@ -2,7 +2,7 @@
    
    client.c for the Openbox window manager
    Copyright (c) 2006        Mikael Magnusson
-   Copyright (c) 2003        Ben Jansens
+   Copyright (c) 2003-2007   Dana Jansens
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -68,6 +68,7 @@ static void client_get_startup_id(ObClient *self);
 static void client_get_area(ObClient *self);
 static void client_get_desktop(ObClient *self);
 static void client_get_state(ObClient *self);
+static void client_get_layer(ObClient *self);
 static void client_get_shaped(ObClient *self);
 static void client_get_mwm_hints(ObClient *self);
 static void client_get_gravity(ObClient *self);
@@ -460,11 +461,28 @@ void client_manage(Window window)
     mouse_grab_for_client(self, TRUE);
 
     if (activate) {
-        /* This is focus stealing prevention, if a user_time has been set */
+        /* This is focus stealing prevention */
         ob_debug("Want to focus new window 0x%x with time %u (last time %u)\n",
                  self->window, self->user_time, client_last_user_time);
-        if (!self->user_time || self->user_time >= client_last_user_time ||
-            client_search_focus_parent(self) != NULL)
+
+        /* If a nothing at all, or a parent was focused, then focus this
+           always
+        */
+        if (!focus_client || client_search_focus_parent(self) != NULL)
+            activate = TRUE;
+        else
+        {
+            /* If time stamp is old, don't steal focus */
+            if (self->user_time && self->user_time < client_last_user_time)
+                activate = FALSE;
+            /* Don't steal focus from globally active clients.
+               I stole this idea from KWin. It seems nice.
+             */
+            if (!focus_client->can_focus && focus_client->focus_notify)
+                activate = FALSE;
+        }
+
+        if (activate)
         {
             /* since focus can change the stacking orders, if we focus the
                window then the standard raise it gets is not enough, we need
@@ -477,9 +495,6 @@ void client_manage(Window window)
             /* if the client isn't focused, then hilite it so the user
                knows it is there */
             client_hilite(self, TRUE);
-
-            /* don't focus it ! (focus stealing prevention) */
-            activate = FALSE;
         }
     }
     else {
@@ -864,6 +879,7 @@ static void client_get_all(ObClient *self)
        work right (eg tsclient). */
     client_update_transient_for(self);
     client_get_type(self);/* this can change the mwmhints for special cases */
+    client_get_state(self);
     client_update_transient_for(self);
 
     client_update_wmhints(self);
@@ -872,7 +888,8 @@ static void client_get_all(ObClient *self)
                                 desktop is not specified */
     client_get_shaped(self);
 
-    client_get_state(self);
+    client_get_layer(self); /* if layer hasn't been specified, get it from
+                               other sources if possible */
 
     {
         /* a couple type-based defaults for new windows */
@@ -965,6 +982,41 @@ static void client_get_desktop(ObClient *self)
     }
 }
 
+static void client_get_layer(ObClient *self)
+{
+    if (!(self->above || self->below)) {
+        if (self->group) {
+            /* apply stuff from the group */
+            GSList *it;
+            gint layer = -2;
+
+            for (it = self->group->members; it; it = g_slist_next(it)) {
+                ObClient *c = it->data;
+                if (c != self && !client_search_transient(self, c) &&
+                    client_normal(self) && client_normal(c))
+                {
+                    layer = MAX(layer,
+                                (c->above ? 1 : (c->below ? -1 : 0)));
+                }
+            }
+            switch (layer) {
+            case -1:
+                self->below = TRUE;
+                break;
+            case -2:
+            case 0:
+                break;
+            case 1:
+                self->above = TRUE;
+                break;
+            default:
+                g_assert_not_reached();
+                break;
+            }
+        }
+    }
+}
+
 static void client_get_state(ObClient *self)
 {
     guint32 *state;
@@ -1001,38 +1053,6 @@ static void client_get_state(ObClient *self)
 
         g_free(state);
     }
-
-    if (!(self->above || self->below)) {
-        if (self->group) {
-            /* apply stuff from the group */
-            GSList *it;
-            gint layer = -2;
-
-            for (it = self->group->members; it; it = g_slist_next(it)) {
-                ObClient *c = it->data;
-                if (c != self && !client_search_transient(self, c) &&
-                    client_normal(self) && client_normal(c))
-                {
-                    layer = MAX(layer,
-                                (c->above ? 1 : (c->below ? -1 : 0)));
-                }
-            }
-            switch (layer) {
-            case -1:
-                self->below = TRUE;
-                break;
-            case -2:
-            case 0:
-                break;
-            case 1:
-                self->above = TRUE;
-                break;
-            default:
-                g_assert_not_reached();
-                break;
-            }
-        }
-    }
 }
 
 static void client_get_shaped(ObClient *self)
@@ -1071,25 +1091,31 @@ void client_update_transient_for(ObClient *self)
                 target = NULL;
             }
 
-#if 0 
-/* we used to do this, but it violates the ICCCM and causes problems because
-   toolkits seem to set transient_for = root rather arbitrarily (eg kicker's
-   config dialogs), so it is being removed. the ewmh provides other ways to
-   make things transient for their group. -dana
-*/
+            /* THIS IS SO ANNOYING ! ! ! ! Let me explain.... have a seat..
+
+               Setting the transient_for to Root is actually illegal, however
+               applications from time have done this to specify transient for
+               their group.
+
+               Now you can do that by being a TYPE_DIALOG and not setting
+               the transient_for hint at all on your window. But people still
+               use Root, and Kwin is very strange in this regard.
+
+               KWin 3.0 will not consider windows with transient_for set to
+               Root as transient for their group *UNLESS* they are also modal.
+               In that case, it will make them transient for the group. This
+               leads to all sorts of weird behavior from KDE apps which are
+               only tested in KWin. I'd like to follow their behavior just to
+               make this work right with KDE stuff, but that seems wrong.
+            */
             if (!target && self->group) {
                 /* not transient to a client, see if it is transient for a
                    group */
-                if (t == self->group->leader ||
-                    t == None ||
-                    t == RootWindow(ob_display, ob_screen))
-                {
+                if (t == RootWindow(ob_display, ob_screen)) {
                     /* window is a transient for its group! */
                     target = OB_TRAN_GROUP;
                 }
             }
-#endif
-
         }
     } else if (self->type == OB_CLIENT_TYPE_DIALOG && self->group) {
         self->transient = TRUE;
@@ -1978,8 +2004,6 @@ static void client_calc_layer_recursive(ObClient *self, ObClient *orig,
     own = calc_layer(self);
     self->layer = MAX(own, min);
 
-    ob_debug("layer for %s: %d\n", self->title, self->layer);
-
     for (it = self->transients; it; it = g_slist_next(it))
         client_calc_layer_recursive(it->data, orig,
                                     self->layer,
This page took 0.024904 seconds and 4 git commands to generate.