- for (it = focus_order[screen_desktop]; it != NULL; it = it->next)
- if (type != OB_FOCUS_FALLBACK_UNFOCUSING || it->data != old)
- if (client_normal(it->data) && client_can_focus(it->data))
- return it->data;
+ ob_debug_type(OB_DEBUG_FOCUS, "trying omnipresentness\n");
+ if (allow_refocus && old && old->desktop == DESKTOP_ALL)
+ return old;
+
+
+ ob_debug_type(OB_DEBUG_FOCUS, "trying the focus order\n");
+ for (it = focus_order; it; it = g_list_next(it))
+ if (allow_refocus || it->data != old) {
+ ObClient *c = it->data;
+ /* fallback focus to a window if:
+ 1. it is actually focusable, cuz if it's not then we're sending
+ focus off to nothing
+ 2. it is validated. if the window is about to disappear, then
+ don't try focus it.
+ 3. it is visible on the current desktop. this ignores
+ omnipresent windows, which are problematic in their own rite.
+ 4. it's not iconic
+ 5. it is a normal type window, don't fall back onto a dock or
+ a splashscreen or a desktop window (save the desktop as a
+ backup fallback though)
+ */
+ if (client_can_focus(c) && c->desktop == screen_desktop &&
+ !c->iconic)
+ {
+ if (client_normal(c)) {
+ ob_debug_type(OB_DEBUG_FOCUS, "found in focus order\n");
+ return it->data;
+ } else if (c->type == OB_CLIENT_TYPE_DESKTOP && !desktop)
+ desktop = c;
+ }
+ }