]> Dogcows Code - chaz/openbox/blobdiff - openbox/focus.c
add an allDesktops option to Next/PreviousWindow to alt-tab across all desktops.
[chaz/openbox] / openbox / focus.c
index c1d5147773aac2366b27f138648885a7f238e35b..755b6ceabe787f8f3f94f86a042d4d25b361f4da 100644 (file)
@@ -37,6 +37,8 @@
 #include <glib.h>
 #include <assert.h>
 
+#define FOCUS_INDICATOR_WIDTH 5
+
 ObClient *focus_client = NULL;
 GList *focus_order = NULL;
 ObClient *focus_cycle_target = NULL;
@@ -59,7 +61,7 @@ static void focus_cycle_destructor(ObClient *client, gpointer data)
        be used
     */
     if (focus_cycle_target == client)
-        focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
+        focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
 }
 
 static Window createWindow(Window parent, gulong mask,
@@ -168,7 +170,7 @@ void focus_set_client(ObClient *client)
        be used.
     */
     if (focus_cycle_target)
-        focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
+        focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
 
     focus_client = client;
 
@@ -232,24 +234,19 @@ ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *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
+               focus off to nothing. this includes if it is visible right now
+               2. it is on the current desktop. this ignores omnipresent
+               windows, which are problematic in their own rite.
+               3. 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->iconic)
+            if (client_can_focus(c))
             {
                 if (c->desktop == screen_desktop && client_normal(c)) {
                     ob_debug_type(OB_DEBUG_FOCUS, "found in focus order\n");
                     return it->data;
-                } else if ((c->desktop == screen_desktop ||
-                            c->desktop == DESKTOP_ALL) &&
-                           c->type == OB_CLIENT_TYPE_DESKTOP && 
+                } else if (c->type == OB_CLIENT_TYPE_DESKTOP && 
                            desktop == NULL)
                     desktop = c;
             }
@@ -345,10 +342,7 @@ void focus_cycle_draw_indicator()
         gint x, y, w, h;
         gint wt, wl, wr, wb;
 
-        wt = wl = wr = wb = MAX(3,
-                                MAX(1, MAX(ob_rr_theme->paddingx,
-                                           ob_rr_theme->paddingy)) * 2 +
-                                ob_rr_theme->fbwidth * 2);
+        wt = wl = wr = wb = FOCUS_INDICATOR_WIDTH;
 
         x = focus_cycle_target->frame->area.x;
         y = focus_cycle_target->frame->area.y;
@@ -463,7 +457,9 @@ void focus_cycle_draw_indicator()
     }
 }
 
-static gboolean valid_focus_target(ObClient *ft, gboolean dock_windows)
+static gboolean valid_focus_target(ObClient *ft,
+                                   gboolean all_desktops,
+                                   gboolean dock_windows)
 {
     gboolean ok = FALSE;
     /* we don't use client_can_focus here, because that doesn't let you
@@ -475,13 +471,23 @@ static gboolean valid_focus_target(ObClient *ft, gboolean dock_windows)
     else
         ok = (ft->type == OB_CLIENT_TYPE_NORMAL ||
               ft->type == OB_CLIENT_TYPE_DIALOG ||
-              (!client_has_group_siblings(ft) &&
-               (ft->type == OB_CLIENT_TYPE_TOOLBAR ||
+              ((ft->type == OB_CLIENT_TYPE_TOOLBAR ||
                 ft->type == OB_CLIENT_TYPE_MENU ||
-                ft->type == OB_CLIENT_TYPE_UTILITY)));
+                ft->type == OB_CLIENT_TYPE_UTILITY) &&
+               /* let alt-tab go to these windows when a window in its group
+                  already has focus ... */
+               ((focus_client && ft->group == focus_client->group) ||
+                /* ... or if there are no application windows in its group */
+                !client_has_application_group_siblings(ft))));
     ok = ok && (ft->can_focus || ft->focus_notify);
-    ok = ok && !ft->skip_pager;
-    ok = ok && (ft->desktop == screen_desktop || ft->desktop == DESKTOP_ALL);
+    if (!dock_windows && /* use dock windows that skip taskbar too */
+        !(ft->type == OB_CLIENT_TYPE_TOOLBAR || /* also, if we actually are */
+          ft->type == OB_CLIENT_TYPE_MENU ||    /* being allowed to target */
+          ft->type == OB_CLIENT_TYPE_UTILITY))  /* one of these, don't let */
+        ok = ok && !ft->skip_taskbar;           /*  skip taskbar stop us */
+    if (!all_desktops)
+        ok = ok && (ft->desktop == screen_desktop ||
+                    ft->desktop == DESKTOP_ALL);
     ok = ok && ft == client_focus_target(ft);
     return ok;
 /*
@@ -491,7 +497,7 @@ static gboolean valid_focus_target(ObClient *ft, gboolean dock_windows)
         for (it = ft->transients; it; it = g_slist_next(it)) {
             ObClient *c = it->data;
 
-            if (c->frame->visible)
+            if (frame_visible(c->frame))
                 return FALSE;
         }
         return TRUE;
@@ -499,7 +505,8 @@ static gboolean valid_focus_target(ObClient *ft, gboolean dock_windows)
 */
 }
 
-void focus_cycle(gboolean forward, gboolean dock_windows,
+void focus_cycle(gboolean forward, gboolean all_desktops,
+                 gboolean dock_windows,
                  gboolean linear, gboolean interactive,
                  gboolean dialog, gboolean done, gboolean cancel)
 {
@@ -544,7 +551,7 @@ void focus_cycle(gboolean forward, gboolean dock_windows,
             if (it == NULL) it = g_list_last(list);
         }
         ft = it->data;
-        if (valid_focus_target(ft, dock_windows)) {
+        if (valid_focus_target(ft, all_desktops, dock_windows)) {
             if (interactive) {
                 if (ft != focus_cycle_target) { /* prevents flicker */
                     focus_cycle_target = ft;
@@ -710,7 +717,7 @@ void focus_directional_cycle(ObDirection dir, gboolean dock_windows,
         GList *it;
 
         for (it = focus_order; it; it = g_list_next(it))
-            if (valid_focus_target(it->data, dock_windows))
+            if (valid_focus_target(it->data, FALSE, dock_windows))
                 ft = it->data;
     }
         
This page took 0.028847 seconds and 4 git commands to generate.