]> Dogcows Code - chaz/openbox/blobdiff - openbox/focus.c
save the focus_client when falling back, so we don't actually refocus it when we...
[chaz/openbox] / openbox / focus.c
index 73cb6f52c9b096d53cc5150c85d179c85e911184..d18b3a1f428cfef066e9ab0f68fe914cebba5ebd 100644 (file)
@@ -2,7 +2,7 @@
 
    focus.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
@@ -223,8 +223,12 @@ static ObClient *find_transient_recursive(ObClient *c, ObClient *top,
     for (it = c->transients; it; it = g_slist_next(it)) {
         if (it->data == top) return NULL;
         ret = find_transient_recursive(it->data, top, skip);
-        if (ret && ret != skip && client_normal(ret)) return ret;
-        if (it->data != skip && client_normal(it->data)) return it->data;
+        if (ret && ret != skip && client_normal(ret) &&
+            client_can_focus(ret) && client_validate(ret))
+            return ret;
+        if (it->data != skip && client_normal(it->data) &&
+            client_can_focus(it->data) && client_validate(it->data))
+            return it->data;
     }
     return NULL;
 }
@@ -244,66 +248,62 @@ static ObClient* focus_fallback_transient(ObClient *top, ObClient *old)
         return NULL;
 }
 
-ObClient* focus_fallback_target(ObFocusFallbackType type)
+ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old)
 {
     GList *it;
-    ObClient *old = NULL;
     ObClient *target = NULL;
 
-    old = focus_client;
-
-    if ((type == OB_FOCUS_FALLBACK_UNFOCUSING
-         || type == OB_FOCUS_FALLBACK_CLOSED) && old) {
-        if (old->transient_for) {
-            gboolean trans = FALSE;
-
-            if (!config_focus_follow || config_focus_last)
-                trans = TRUE;
-            else {
-                if ((target = client_under_pointer())) {
+    if (!allow_refocus && old && old->transient_for) {
+        gboolean trans = FALSE;
+
+        if (!config_focus_follow || config_focus_last)
+            trans = TRUE;
+        else if ((target = client_under_pointer()) &&
+                 client_search_transient
+                 (client_search_top_parent(target), old))
+            trans = TRUE;
+
+        /* try for transient relations */
+        if (trans) {
+            if (old->transient_for == OB_TRAN_GROUP) {
+                for (it = focus_order[screen_desktop]; it;
+                     it = g_list_next(it))
+                {
                     GSList *sit;
 
-                    sit = client_search_top_transients(target);
-                    for (; sit; sit = g_slist_next(sit))
-                        if (client_search_transient(sit->data, old)) {
-                            trans = TRUE;
-                            break;
-                        }
-                }
-            }
-
-            /* try for transient relations */
-            if (trans) {
-                if (old->transient_for == OB_TRAN_GROUP) {
-                    for (it = focus_order[screen_desktop]; it;
-                         it = g_list_next(it))
+                    for (sit = old->group->members; sit;
+                         sit = g_slist_next(sit))
                     {
-                        GSList *sit;
-
-                        for (sit = old->group->members; sit;
-                             sit = g_slist_next(sit))
-                        {
-                            if (sit->data == it->data)
-                                if ((target =
-                                     focus_fallback_transient(sit->data, old)))
-                                    return target;
-                        }
+                        if (sit->data == it->data)
+                            if ((target =
+                                 focus_fallback_transient(sit->data, old)))
+                            {
+                                ob_debug("found in transient #1\n");
+                                return target;
+                            }
                     }
-                } else {
-                    if ((target =
-                         focus_fallback_transient(old->transient_for, old)))
-                        return target;
+                }
+            } else {
+                if ((target =
+                     focus_fallback_transient(old->transient_for, old)))
+                {
+                    ob_debug("found in transient #2\n");
+                    return target;
                 }
             }
         }
     }
 
-    if (config_focus_follow &&
-        (type == OB_FOCUS_FALLBACK_UNFOCUSING || !config_focus_last))
+    ob_debug("trying pointer stuff\n");
+    if (config_focus_follow && !config_focus_last)
     {
         if ((target = client_under_pointer()))
-            if (client_normal(target) && client_can_focus(target))
-                return target;
+            if (allow_refocus || target != old)
+                if (client_normal(target) && client_can_focus(target) &&
+                    client_validate(target)) {
+                    ob_debug("found in pointer stuff\n");
+                    return target;
+                }
     }
 
 #if 0
@@ -320,10 +320,15 @@ ObClient* focus_fallback_target(ObFocusFallbackType type)
         }
 #endif
 
+    ob_debug("trying  the focus order\n");
     for (it = focus_order[screen_desktop]; it; it = g_list_next(it))
-        if (type != OB_FOCUS_FALLBACK_UNFOCUSING || it->data != old)
-            if (client_normal(it->data) && client_can_focus(it->data))
+        if (allow_refocus || it->data != old)
+            if (client_normal(it->data) && client_can_focus(it->data) &&
+                client_validate(it->data))
+            {
+                ob_debug("found in focus order\n");
                 return it->data;
+            }
 
     /* XXX fallback to the "desktop window" if one exists ?
        could store it while going through all the windows in the loop right
@@ -333,9 +338,13 @@ ObClient* focus_fallback_target(ObFocusFallbackType type)
     return NULL;
 }
 
-void focus_fallback(ObFocusFallbackType type)
+void focus_fallback(gboolean allow_refocus)
 {
     ObClient *new;
+    ObClient *old;
+
+    /* save this before moving focus away to nothing */
+    old = focus_client;
 
     /* unfocus any focused clients.. they can be focused by Pointer events
        and such, and then when I try focus them, I won't get a FocusIn event
@@ -343,7 +352,7 @@ void focus_fallback(ObFocusFallbackType type)
     */
     focus_set_client(NULL);
 
-    if ((new = focus_fallback_target(type)))
+    if ((new = focus_fallback_target(allow_refocus, old)))
         client_focus(new);
 }
 
This page took 0.030515 seconds and 4 git commands to generate.