]> Dogcows Code - chaz/openbox/blobdiff - openbox/client.c
i rewrote handling of focus events. this is pretty much based on blackbox's current...
[chaz/openbox] / openbox / client.c
index 8358293dcfd5f8f178be90bd10fb1acbaf2d1a40..e4bef71d8392571db3a297a8ec35faf34d8538ed 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
@@ -45,8 +45,7 @@
 #include <X11/Xutil.h>
 
 /*! The event mask to grab on client windows */
-#define CLIENT_EVENTMASK (PropertyChangeMask | FocusChangeMask | \
-                          StructureNotifyMask)
+#define CLIENT_EVENTMASK (PropertyChangeMask | StructureNotifyMask)
 
 #define CLIENT_NOPROPAGATEMASK (ButtonPressMask | ButtonReleaseMask | \
                                 ButtonMotionMask)
@@ -469,9 +468,7 @@ void client_manage(Window window)
            always
         */
         if (!focus_client || client_search_focus_parent(self) != NULL)
-        {
             activate = TRUE;
-        }
         else
         {
             /* If time stamp is old, don't steal focus */
@@ -481,9 +478,7 @@ void client_manage(Window window)
                I stole this idea from KWin. It seems nice.
              */
             if (!focus_client->can_focus && focus_client->focus_notify)
-            {
                 activate = FALSE;
-            }
         }
 
         if (activate)
@@ -559,7 +554,8 @@ void client_unmanage(ObClient *self)
     guint j;
     GSList *it;
 
-    ob_debug("Unmanaging window: %lx (%s)\n", self->window, self->class);
+    ob_debug("Unmanaging window: %lx (%s) (%s)\n", self->window, self->class,
+             self->title ? self->title : "");
 
     g_assert(self != NULL);
 
@@ -1121,9 +1117,15 @@ void client_update_transient_for(ObClient *self)
                 }
             }
         }
-    } else if (self->type == OB_CLIENT_TYPE_DIALOG && self->group) {
-        self->transient = TRUE;
-        target = OB_TRAN_GROUP;
+    } else if (self->group) {
+        if (self->type == OB_CLIENT_TYPE_DIALOG ||
+            self->type == OB_CLIENT_TYPE_TOOLBAR ||
+            self->type == OB_CLIENT_TYPE_MENU ||
+            self->type == OB_CLIENT_TYPE_UTILITY)
+        {
+            self->transient = TRUE;
+            target = OB_TRAN_GROUP;
+        }
     } else
         self->transient = FALSE;
 
@@ -2008,8 +2010,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,
@@ -2030,7 +2030,7 @@ void client_calc_layer(ObClient *self)
     orig = self;
 
     /* transients take on the layer of their parents */
-    it = client_search_top_transients(self);
+    it = client_search_all_top_parents(self);
 
     for (; it; it = g_slist_next(it))
         client_calc_layer_recursive(it->data, orig, 0, FALSE);
@@ -2455,21 +2455,18 @@ static void client_iconify_recursive(ObClient *self,
             screen_update_areas();
     }
 
-    /* iconify all transients */
+    /* iconify all direct transients */
     for (it = self->transients; it; it = g_slist_next(it))
-        if (it->data != self) client_iconify_recursive(it->data,
-                                                       iconic, curdesk);
+        if (it->data != self)
+            if (client_is_direct_child(self, it->data))
+                client_iconify_recursive(it->data, iconic, curdesk);
 }
 
 void client_iconify(ObClient *self, gboolean iconic, gboolean curdesk)
 {
-    GSList *it;
-
     /* move up the transient chain as far as possible first */
-    it = client_search_top_transients(self);
-
-    for (; it; it = g_slist_next(it))
-    client_iconify_recursive(it->data, iconic, curdesk);
+    self = client_search_top_parent(self);
+    client_iconify_recursive(self, iconic, curdesk);
 }
 
 void client_maximize(ObClient *self, gboolean max, gint dir, gboolean savearea)
@@ -2616,6 +2613,9 @@ void client_kill(ObClient *self)
 
 void client_hilite(ObClient *self, gboolean hilite)
 {
+    if (self->demands_attention == hilite)
+        return; /* no change */
+
     /* don't allow focused windows to hilite */
     self->demands_attention = hilite && !client_focused(self);
     if (self->demands_attention)
@@ -2663,18 +2663,23 @@ void client_set_desktop_recursive(ObClient *self,
 
     /* move all transients */
     for (it = self->transients; it; it = g_slist_next(it))
-        if (it->data != self) client_set_desktop_recursive(it->data,
-                                                           target, donthide);
+        if (it->data != self)
+            if (client_is_direct_child(self, it->data))
+                client_set_desktop_recursive(it->data, target, donthide);
 }
 
 void client_set_desktop(ObClient *self, guint target, gboolean donthide)
 {
-    GSList *it;
-
-    it = client_search_top_transients(self);
+    self = client_search_top_parent(self);
+    client_set_desktop_recursive(self, target, donthide);
+}
 
-    for(; it; it = g_slist_next(it))
-        client_set_desktop_recursive(it->data, target, donthide);
+gboolean client_is_direct_child(ObClient *parent, ObClient *child)
+{
+    while (child != parent &&
+           child->transient_for && child->transient_for != OB_TRAN_GROUP)
+        child = child->transient_for;
+    return child == parent;
 }
 
 ObClient *client_search_modal_child(ObClient *self)
@@ -2940,6 +2945,8 @@ gboolean client_focus(ObClient *self)
         return FALSE;
     }
 
+    ob_debug("Focusing client \"%s\" at time %u\n", self->title, event_curtime);
+
     if (self->can_focus) {
         /* RevertToPointerRoot causes much more headache than RevertToNone, so
            I choose to use it always, hopefully to find errors quicker, if any
@@ -3242,7 +3249,14 @@ guint client_monitor(ObClient *self)
     return screen_find_monitor(&self->frame->area);
 }
 
-GSList *client_search_top_transients(ObClient *self)
+ObClient *client_search_top_parent(ObClient *self)
+{
+    while (self->transient_for && self->transient_for != OB_TRAN_GROUP)
+        self = self->transient_for;
+    return self;
+}
+
+GSList *client_search_all_top_parents(ObClient *self)
 {
     GSList *ret = NULL;
 
This page took 0.025912 seconds and 4 git commands to generate.