make focus_order into one long list instead of having one per desktop. this actually...
authorDana Jansens <danakj@orodu.net>
Wed, 14 Mar 2007 21:07:30 +0000 (21:07 +0000)
committerDana Jansens <danakj@orodu.net>
Wed, 14 Mar 2007 21:07:30 +0000 (21:07 +0000)
also this is not tested. sorry if it breaks everything.

openbox/client_list_combined_menu.c
openbox/client_list_menu.c
openbox/focus.c
openbox/focus.h
openbox/place.c
openbox/screen.c

index f590dc1..39a8e60 100644 (file)
@@ -55,9 +55,11 @@ static void self_update(ObMenuFrame *frame, gpointer data)
         e->data.normal.label = g_strdup(screen_desktop_names[desktop]);
         /* The one at the bottom will always have entries below it though */
         menu_add_separator(menu, -1);
-        for (it = focus_order[desktop], i = 0; it; it = g_list_next(it), ++i) {
+        for (it = focus_order, i = 0; it; it = g_list_next(it), ++i) {
             ObClient *c = it->data;
-            if (client_normal(c) && (!c->skip_taskbar || c->iconic)) {
+            if (client_normal(c) && (!c->skip_taskbar || c->iconic) &&
+                (c->desktop == desktop || c->desktop == DESKTOP_ALL))
+            {
                 GSList *acts = NULL;
                 ObAction* act;
                 const ObClientIcon *icon;
index d703bab..f49f623 100644 (file)
@@ -49,9 +49,11 @@ static void desk_menu_update(ObMenuFrame *frame, gpointer data)
 
     menu_clear_entries(menu);
 
-    for (it = focus_order[d->desktop], i = 0; it; it = g_list_next(it), ++i) {
+    for (it = focus_order, i = 0; it; it = g_list_next(it), ++i) {
         ObClient *c = it->data;
-        if (client_normal(c) && (!c->skip_taskbar || c->iconic)) {
+        if (client_normal(c) && (!c->skip_taskbar || c->iconic) &&
+            (c->desktop == d->desktop || c->desktop == DESKTOP_ALL))
+        {
             GSList *acts = NULL;
             ObAction* act;
             ObMenuEntry *e;
index d18b3a1..4be187b 100644 (file)
@@ -38,8 +38,7 @@
 #include <assert.h>
 
 ObClient *focus_client, *focus_hilite;
-GList **focus_order; /* these lists are created when screen_startup
-                        sets the number of desktops */
+GList *focus_order;
 ObClient *focus_cycle_target;
 
 struct {
@@ -129,17 +128,11 @@ void focus_startup(gboolean reconfig)
 
 void focus_shutdown(gboolean reconfig)
 {
-    guint i;
-
     icon_popup_free(focus_cycle_popup);
 
     if (!reconfig) {
         client_remove_destructor(focus_cycle_destructor);
 
-        for (i = 0; i < screen_num_desktops; ++i)
-            g_list_free(focus_order[i]);
-        g_free(focus_order);
-
         /* reset focus to root */
         XSetInputFocus(ob_display, PointerRoot, RevertToNone, CurrentTime);
 
@@ -156,12 +149,8 @@ void focus_shutdown(gboolean reconfig)
 
 static void push_to_top(ObClient *client)
 {
-    guint desktop;
-
-    desktop = client->desktop;
-    if (desktop == DESKTOP_ALL) desktop = screen_desktop;
-    focus_order[desktop] = g_list_remove(focus_order[desktop], client);
-    focus_order[desktop] = g_list_prepend(focus_order[desktop], client);
+    focus_order = g_list_remove(focus_order, client);
+    focus_order = g_list_prepend(focus_order, client);
 }
 
 void focus_set_client(ObClient *client)
@@ -212,87 +201,11 @@ void focus_set_client(ObClient *client)
     }
 }
 
-/* finds the first transient that isn't 'skip' and ensure's that client_normal
- is true for it */
-static ObClient *find_transient_recursive(ObClient *c, ObClient *top,
-                                          ObClient *skip)
-{
-    GSList *it;
-    ObClient *ret;
-
-    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) &&
-            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;
-}
-
-static ObClient* focus_fallback_transient(ObClient *top, ObClient *old)
-{
-    ObClient *target = find_transient_recursive(top, top, old);
-    if (!target) {
-        /* make sure client_normal is true always */
-        if (!client_normal(top))
-            return NULL;
-        target = top; /* no transient, keep the top */
-    }
-    if (client_can_focus(target))
-        return target;
-    else
-        return NULL;
-}
-
 ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old)
 {
     GList *it;
     ObClient *target = NULL;
-
-    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;
-
-                    for (sit = old->group->members; sit;
-                         sit = g_slist_next(sit))
-                    {
-                        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)))
-                {
-                    ob_debug("found in transient #2\n");
-                    return target;
-                }
-            }
-        }
-    }
+    ObClient *desktop = NULL;
 
     ob_debug("trying pointer stuff\n");
     if (config_focus_follow && !config_focus_last)
@@ -321,21 +234,34 @@ ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old)
 #endif
 
     ob_debug("trying  the focus order\n");
-    for (it = focus_order[screen_desktop]; it; it = g_list_next(it))
-        if (allow_refocus || it->data != old)
-            if (client_normal(it->data) && client_can_focus(it->data) &&
-                client_validate(it->data))
+    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 screen right now.
+               4. 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) && client_validate(c) &&
+                client_should_show(c))
             {
-                ob_debug("found in focus order\n");
-                return it->data;
+                if (client_normal(c)) {
+                    ob_debug("found in focus order\n");
+                    return it->data;
+                } else if (c->type == OB_CLIENT_TYPE_DESKTOP && !desktop)
+                    desktop = c;
             }
+        }
 
-    /* XXX fallback to the "desktop window" if one exists ?
-       could store it while going through all the windows in the loop right
-       above this..
+    /* as a last resort fallback to the desktop window if there is one.
+       (if there's more than one, then the one last focused.)
     */
-
-    return NULL;
+    return desktop;   
 }
 
 void focus_fallback(gboolean allow_refocus)
@@ -579,15 +505,15 @@ void focus_cycle(gboolean forward, gboolean linear, gboolean interactive,
         } else if (done)
             goto done_cycle;
 
-        if (!focus_order[screen_desktop])
+        if (!focus_order)
             goto done_cycle;
 
         if (!first) first = focus_client;
 
         if (linear) list = client_list;
-        else        list = focus_order[screen_desktop];
+        else        list = focus_order;
     } else {
-        if (!focus_order[screen_desktop])
+        if (!focus_order)
             goto done_cycle;
         list = client_list;
     }
@@ -657,7 +583,7 @@ void focus_directional_cycle(ObDirection dir, gboolean interactive,
     } else if (done)
         goto done_cycle;
 
-    if (!focus_order[screen_desktop])
+    if (!focus_order)
         goto done_cycle;
 
     if (!first) first = focus_client;
@@ -668,7 +594,7 @@ void focus_directional_cycle(ObDirection dir, gboolean interactive,
     else {
         GList *it;
 
-        for (it = focus_order[screen_desktop]; it; it = g_list_next(it))
+        for (it = focus_order; it; it = g_list_next(it))
             if (valid_focus_target(it->data))
                 ft = it->data;
     }
@@ -701,92 +627,61 @@ done_cycle:
 
 void focus_order_add_new(ObClient *c)
 {
-    guint d, i;
-
     if (c->iconic)
         focus_order_to_top(c);
     else {
-        d = c->desktop;
-        if (d == DESKTOP_ALL) {
-            for (i = 0; i < screen_num_desktops; ++i) {
-                g_assert(!g_list_find(focus_order[i], c));
-                if (focus_order[i] && ((ObClient*)focus_order[i]->data)->iconic)
-                    focus_order[i] = g_list_insert(focus_order[i], c, 0);
-                else
-                    focus_order[i] = g_list_insert(focus_order[i], c, 1);
-            }
-        } else {
-            g_assert(!g_list_find(focus_order[d], c));
-            if (focus_order[d] && ((ObClient*)focus_order[d]->data)->iconic)
-                focus_order[d] = g_list_insert(focus_order[d], c, 0);
-            else
-                focus_order[d] = g_list_insert(focus_order[d], c, 1);
-        }
+        g_assert(!g_list_find(focus_order, c));
+        /* if there are any iconic windows, put this above them in the order,
+           but if there are not, then put it under the currently focused one */
+        if (focus_order && ((ObClient*)focus_order->data)->iconic)
+            focus_order = g_list_insert(focus_order, c, 0);
+        else
+            focus_order = g_list_insert(focus_order, c, 1);
     }
 }
 
 void focus_order_remove(ObClient *c)
 {
-    guint d, i;
-
-    d = c->desktop;
-    if (d == DESKTOP_ALL) {
-        for (i = 0; i < screen_num_desktops; ++i)
-            focus_order[i] = g_list_remove(focus_order[i], c);
-    } else
-        focus_order[d] = g_list_remove(focus_order[d], c);
+    focus_order = g_list_remove(focus_order, c);
 }
 
-static void to_top(ObClient *c, guint d)
+void focus_order_to_top(ObClient *c)
 {
-    focus_order[d] = g_list_remove(focus_order[d], c);
+    focus_order = g_list_remove(focus_order, c);
     if (!c->iconic) {
-        focus_order[d] = g_list_prepend(focus_order[d], c);
+        focus_order = g_list_prepend(focus_order, c);
     } else {
         GList *it;
 
         /* insert before first iconic window */
-        for (it = focus_order[d];
+        for (it = focus_order;
              it && !((ObClient*)it->data)->iconic; it = g_list_next(it));
-        focus_order[d] = g_list_insert_before(focus_order[d], it, c);
+        focus_order = g_list_insert_before(focus_order, it, c);
     }
 }
 
-void focus_order_to_top(ObClient *c)
-{
-    guint d, i;
-
-    d = c->desktop;
-    if (d == DESKTOP_ALL) {
-        for (i = 0; i < screen_num_desktops; ++i)
-            to_top(c, i);
-    } else
-        to_top(c, d);
-}
-
-static void to_bottom(ObClient *c, guint d)
+void focus_order_to_bottom(ObClient *c)
 {
-    focus_order[d] = g_list_remove(focus_order[d], c);
+    focus_order = g_list_remove(focus_order, c);
     if (c->iconic) {
-        focus_order[d] = g_list_append(focus_order[d], c);
+        focus_order = g_list_append(focus_order, c);
     } else {
         GList *it;
 
         /* insert before first iconic window */
-        for (it = focus_order[d];
+        for (it = focus_order;
              it && !((ObClient*)it->data)->iconic; it = g_list_next(it));
-        focus_order[d] = g_list_insert_before(focus_order[d], it, c);
+        focus_order = g_list_insert_before(focus_order, it, c);
     }
 }
 
-void focus_order_to_bottom(ObClient *c)
+ObClient *focus_order_find_first(guint desktop)
 {
-    guint d, i;
-
-    d = c->desktop;
-    if (d == DESKTOP_ALL) {
-        for (i = 0; i < screen_num_desktops; ++i)
-            to_bottom(c, i);
-    } else
-        to_bottom(c, d);
+    GList *it;
+    for (it = focus_order; it; it = g_list_next(it)) {
+        ObClient *c = it->data;
+        if (c->desktop == desktop || c->desktop == DESKTOP_ALL)
+            return c;
+    }
+    return NULL;
 }
index 200d96a..e1d6a6c 100644 (file)
@@ -41,7 +41,7 @@ extern struct _ObClient *focus_hilite;
 extern struct _ObClient *focus_cycle_target;
 
 /*! The recent focus order on each desktop */
-extern GList **focus_order;
+extern GList *focus_order;
 
 void focus_startup(gboolean reconfig);
 void focus_shutdown(gboolean reconfig);
@@ -77,4 +77,6 @@ void focus_order_to_top(struct _ObClient *c);
   very bottom always though). */
 void focus_order_to_bottom(struct _ObClient *c);
 
+struct _ObClient *focus_order_find_first(guint desktop);
+
 #endif
index 260299b..ada0d7c 100644 (file)
@@ -297,11 +297,9 @@ static gboolean place_smart(ObClient *client, gint *x, gint *y,
         if (type == SMART_FULL || type == SMART_FOCUSED) {
             gboolean found_foc = FALSE, stop = FALSE;
             ObClient *foc;
-            GList *list;
 
-            list = focus_order[client->desktop == DESKTOP_ALL ?
-                               screen_desktop : client->desktop];
-            foc = list ? list->data : NULL;
+            foc = focus_order_find_first(client->desktop == DESKTOP_ALL ?
+                                         screen_desktop : client->desktop);
 
             for (; it && !stop; it = g_list_next(it)) {
                 ObClient *c;
index 70de299..8f1f939 100644 (file)
@@ -372,7 +372,7 @@ void screen_resize()
 
 void screen_set_num_desktops(guint num)
 {
-    guint i, old;
+    guint old;
     gulong *viewport;
     GList *it;
 
@@ -410,16 +410,6 @@ void screen_set_num_desktops(guint num)
     /* change our desktop if we're on one that no longer exists! */
     if (screen_desktop >= screen_num_desktops)
         screen_set_desktop(num - 1);
-
-   /* update the focus lists */
-    /* free our lists for the desktops which have disappeared */
-    for (i = num; i < old; ++i)
-        g_list_free(focus_order[i]);
-    /* realloc the array */
-    focus_order = g_renew(GList*, focus_order, num);
-    /* set the new lists to be empty */
-    for (i = old; i < num; ++i)
-        focus_order[i] = NULL;
 }
 
 void screen_set_desktop(guint num)
@@ -888,10 +878,13 @@ void screen_show_desktop(gboolean show)
 
     if (show) {
         /* focus desktop */
-        for (it = focus_order[screen_desktop]; it; it = g_list_next(it))
-            if (((ObClient*)it->data)->type == OB_CLIENT_TYPE_DESKTOP &&
+        for (it = focus_order; it; it = g_list_next(it)) {
+            ObClient *c = it->data;
+            if (c->type == OB_CLIENT_TYPE_DESKTOP &&
+                (c->desktop == screen_desktop || c->desktop == DESKTOP_ALL) &&
                 client_validate(it->data) && client_focus(it->data))
                 break;
+        }
     } else {
         focus_fallback(TRUE);
     }