]> Dogcows Code - chaz/openbox/blobdiff - openbox/focus.c
fallback to desktops properly
[chaz/openbox] / openbox / focus.c
index 4be187b9a7682d8ed13a5edaee3da32dd56eed31..69a0e04948435fe002044c4679864745806cbe41 100644 (file)
@@ -37,9 +37,9 @@
 #include <glib.h>
 #include <assert.h>
 
 #include <glib.h>
 #include <assert.h>
 
-ObClient *focus_client, *focus_hilite;
-GList *focus_order;
-ObClient *focus_cycle_target;
+ObClient *focus_client = NULL;
+GList *focus_order = NULL;
+ObClient *focus_cycle_target = NULL;
 
 struct {
     InternalWindow top;
 
 struct {
     InternalWindow top;
@@ -59,7 +59,7 @@ static void focus_cycle_destructor(ObClient *client, gpointer data)
        be used
     */
     if (focus_cycle_target == client)
        be used
     */
     if (focus_cycle_target == client)
-        focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, CurrentTime);
+        focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
 }
 
 static Window createWindow(Window parent, gulong mask,
 }
 
 static Window createWindow(Window parent, gulong mask,
@@ -81,7 +81,7 @@ void focus_startup(gboolean reconfig)
         client_add_destructor(focus_cycle_destructor, NULL);
 
         /* start with nothing focused */
         client_add_destructor(focus_cycle_destructor, NULL);
 
         /* start with nothing focused */
-        focus_set_client(NULL);
+        focus_nothing();
 
         focus_indicator.top.obwin.type = Window_Internal;
         focus_indicator.left.obwin.type = Window_Internal;
 
         focus_indicator.top.obwin.type = Window_Internal;
         focus_indicator.left.obwin.type = Window_Internal;
@@ -156,48 +156,34 @@ static void push_to_top(ObClient *client)
 void focus_set_client(ObClient *client)
 {
     Window active;
 void focus_set_client(ObClient *client)
 {
     Window active;
-    ObClient *old;
 
 
-#ifdef DEBUG_FOCUS
-    ob_debug("focus_set_client 0x%lx\n", client ? client->window : 0);
-#endif
+    ob_debug_type(OB_DEBUG_FOCUS,
+                  "focus_set_client 0x%lx\n", client ? client->window : 0);
 
     /* uninstall the old colormap, and install the new one */
     screen_install_colormap(focus_client, FALSE);
     screen_install_colormap(client, TRUE);
 
 
     /* uninstall the old colormap, and install the new one */
     screen_install_colormap(focus_client, FALSE);
     screen_install_colormap(client, TRUE);
 
-    if (client == NULL) {
-#ifdef DEBUG_FOCUS
-        ob_debug("actively focusing NONWINDOW\n");
-#endif
-        /* when nothing will be focused, send focus to the backup target */
-        XSetInputFocus(ob_display, screen_support_win, RevertToNone,
-                       event_curtime);
-        XSync(ob_display, FALSE);
-    }
-
     /* in the middle of cycling..? kill it. CurrentTime is fine, time won't
        be used.
     */
     if (focus_cycle_target)
     /* in the middle of cycling..? kill it. CurrentTime is fine, time won't
        be used.
     */
     if (focus_cycle_target)
-        focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, CurrentTime);
+        focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
 
 
-    old = focus_client;
     focus_client = client;
 
     focus_client = client;
 
-    /* move to the top of the list */
-    if (client != NULL)
+    if (client != NULL) {
+        /* move to the top of the list */
         push_to_top(client);
         push_to_top(client);
+        /* remove hiliting from the window when it gets focused */
+        client_hilite(client, FALSE);
+    }
 
     /* set the NET_ACTIVE_WINDOW hint, but preserve it on shutdown */
     if (ob_state() != OB_STATE_EXITING) {
         active = client ? client->window : None;
         PROP_SET32(RootWindow(ob_display, ob_screen),
                    net_active_window, window, active);
 
     /* set the NET_ACTIVE_WINDOW hint, but preserve it on shutdown */
     if (ob_state() != OB_STATE_EXITING) {
         active = client ? client->window : None;
         PROP_SET32(RootWindow(ob_display, ob_screen),
                    net_active_window, window, active);
-
-        /* remove hiliting from the window when it gets focused */
-        if (client != NULL)
-            client_hilite(client, FALSE);
     }
 }
 
     }
 }
 
@@ -207,14 +193,13 @@ ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old)
     ObClient *target = NULL;
     ObClient *desktop = NULL;
 
     ObClient *target = NULL;
     ObClient *desktop = NULL;
 
-    ob_debug("trying pointer stuff\n");
+    ob_debug_type(OB_DEBUG_FOCUS, "trying pointer stuff\n");
     if (config_focus_follow && !config_focus_last)
     {
         if ((target = client_under_pointer()))
             if (allow_refocus || target != old)
     if (config_focus_follow && !config_focus_last)
     {
         if ((target = client_under_pointer()))
             if (allow_refocus || target != old)
-                if (client_normal(target) && client_can_focus(target) &&
-                    client_validate(target)) {
-                    ob_debug("found in pointer stuff\n");
+                if (client_normal(target) && client_can_focus(target)) {
+                    ob_debug_type(OB_DEBUG_FOCUS, "found in pointer stuff\n");
                     return target;
                 }
     }
                     return target;
                 }
     }
@@ -233,7 +218,15 @@ ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old)
         }
 #endif
 
         }
 #endif
 
-    ob_debug("trying  the focus order\n");
+    ob_debug_type(OB_DEBUG_FOCUS, "trying omnipresentness\n");
+    if (allow_refocus && old && old->desktop == DESKTOP_ALL &&
+        client_normal(old))
+    {
+        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;
     for (it = focus_order; it; it = g_list_next(it))
         if (allow_refocus || it->data != old) {
             ObClient *c = it->data;
@@ -242,46 +235,63 @@ ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old)
                focus off to nothing
                2. it is validated. if the window is about to disappear, then
                don't try focus it.
                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
+               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)
             */
                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))
+            if (client_can_focus(c) && !c->iconic)
             {
             {
-                if (client_normal(c)) {
-                    ob_debug("found in focus order\n");
+                if (c->desktop == screen_desktop && client_normal(c)) {
+                    ob_debug_type(OB_DEBUG_FOCUS, "found in focus order\n");
                     return it->data;
                     return it->data;
-                } else if (c->type == OB_CLIENT_TYPE_DESKTOP && !desktop)
+                } else if ((c->desktop == screen_desktop ||
+                            c->desktop == DESKTOP_ALL) &&
+                           c->type == OB_CLIENT_TYPE_DESKTOP && 
+                           desktop == NULL)
                     desktop = c;
             }
         }
 
     /* as a last resort fallback to the desktop window if there is one.
                     desktop = c;
             }
         }
 
     /* as a last resort fallback to the desktop window if there is one.
-       (if there's more than one, then the one last focused.)
+       (if there's more than one, then the one most recently focused.)
     */
     */
+    ob_debug_type(OB_DEBUG_FOCUS, "found desktop: \n", !!desktop);
     return desktop;   
 }
 
 void focus_fallback(gboolean allow_refocus)
 {
     ObClient *new;
     return desktop;   
 }
 
 void focus_fallback(gboolean allow_refocus)
 {
     ObClient *new;
-    ObClient *old;
-
-    /* save this before moving focus away to nothing */
-    old = focus_client;
+    ObClient *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
        at all for them.
     */
 
     /* 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
        at all for them.
     */
-    focus_set_client(NULL);
+    focus_nothing();
 
     if ((new = focus_fallback_target(allow_refocus, old)))
         client_focus(new);
 }
 
 
     if ((new = focus_fallback_target(allow_refocus, old)))
         client_focus(new);
 }
 
+void focus_nothing()
+{
+    /* Install our own colormap */
+    if (focus_client != NULL) {
+        screen_install_colormap(focus_client, FALSE);
+        screen_install_colormap(NULL, TRUE);
+    }
+
+    focus_client = NULL;
+
+    /* when nothing will be focused, send focus to the backup target */
+    XSetInputFocus(ob_display, screen_support_win, RevertToPointerRoot,
+                   event_curtime);
+}
+
 static void popup_cycle(ObClient *c, gboolean show)
 {
     if (!show) {
 static void popup_cycle(ObClient *c, gboolean show)
 {
     if (!show) {
@@ -324,10 +334,15 @@ static void popup_cycle(ObClient *c, gboolean show)
 void focus_cycle_draw_indicator()
 {
     if (!focus_cycle_target) {
 void focus_cycle_draw_indicator()
 {
     if (!focus_cycle_target) {
+        XEvent e;
+
         XUnmapWindow(ob_display, focus_indicator.top.win);
         XUnmapWindow(ob_display, focus_indicator.left.win);
         XUnmapWindow(ob_display, focus_indicator.right.win);
         XUnmapWindow(ob_display, focus_indicator.bottom.win);
         XUnmapWindow(ob_display, focus_indicator.top.win);
         XUnmapWindow(ob_display, focus_indicator.left.win);
         XUnmapWindow(ob_display, focus_indicator.right.win);
         XUnmapWindow(ob_display, focus_indicator.bottom.win);
+
+        /* kill enter events cause by this unmapping */
+        event_ignore_queued_enters();
     } else {
         /*
           if (focus_cycle_target)
     } else {
         /*
           if (focus_cycle_target)
@@ -490,7 +505,7 @@ static gboolean valid_focus_target(ObClient *ft)
 }
 
 void focus_cycle(gboolean forward, gboolean linear, gboolean interactive,
 }
 
 void focus_cycle(gboolean forward, gboolean linear, gboolean interactive,
-                 gboolean dialog, gboolean done, gboolean cancel, Time time)
+                 gboolean dialog, gboolean done, gboolean cancel)
 {
     static ObClient *first = NULL;
     static ObClient *t = NULL;
 {
     static ObClient *first = NULL;
     static ObClient *t = NULL;
@@ -551,7 +566,7 @@ void focus_cycle(gboolean forward, gboolean linear, gboolean interactive,
 
 done_cycle:
     if (done && focus_cycle_target)
 
 done_cycle:
     if (done && focus_cycle_target)
-        client_activate(focus_cycle_target, FALSE, TRUE, time);
+        client_activate(focus_cycle_target, FALSE, TRUE);
 
     t = NULL;
     first = NULL;
 
     t = NULL;
     first = NULL;
@@ -568,8 +583,7 @@ done_cycle:
 }
 
 void focus_directional_cycle(ObDirection dir, gboolean interactive,
 }
 
 void focus_directional_cycle(ObDirection dir, gboolean interactive,
-                             gboolean dialog, gboolean done, gboolean cancel,
-                             Time time)
+                             gboolean dialog, gboolean done, gboolean cancel)
 {
     static ObClient *first = NULL;
     ObClient *ft = NULL;
 {
     static ObClient *first = NULL;
     ObClient *ft = NULL;
@@ -614,7 +628,7 @@ void focus_directional_cycle(ObDirection dir, gboolean interactive,
 
 done_cycle:
     if (done && focus_cycle_target)
 
 done_cycle:
     if (done && focus_cycle_target)
-        client_activate(focus_cycle_target, FALSE, TRUE, time);
+        client_activate(focus_cycle_target, FALSE, TRUE);
 
     first = NULL;
     focus_cycle_target = NULL;
 
     first = NULL;
     focus_cycle_target = NULL;
This page took 0.028367 seconds and 4 git commands to generate.