]> Dogcows Code - chaz/openbox/commitdiff
simplify focus handling a bit. no need to listen to focus going to the frame because...
authorDana Jansens <danakj@orodu.net>
Tue, 15 May 2007 04:32:59 +0000 (04:32 +0000)
committerDana Jansens <danakj@orodu.net>
Tue, 15 May 2007 04:32:59 +0000 (04:32 +0000)
make focus fallback a lil more robust, it checks for errors when it sets focus on the window, and if an error occured it will focus the next option.

openbox/action.c
openbox/client.c
openbox/client.h
openbox/event.c
openbox/focus.c
openbox/openbox.c
openbox/screen.c

index 3f43a238ea6ad7abb51fe79bd1836a7131e00f43..501918599f59ded0a4ce5625a7c5416be78a4ea1 100644 (file)
@@ -1296,7 +1296,7 @@ void action_focus(union ActionData *data)
                go moving on us */
             event_halt_focus_delay();
 
-            client_focus(data->client.any.c);
+            client_focus(data->client.any.c, FALSE);
         }
     } else {
         /* focus action on something other than a client, make keybindings
index 837dd0194a74a8ed4e74a362f8f91e0452f9a3b3..fa4aae9545c37258bcb90056f125bd7092a99c88 100644 (file)
@@ -2842,7 +2842,7 @@ void client_fullscreen(ObClient *self, gboolean fs)
 
     if (fs) {
         /* try focus us when we go into fullscreen mode */
-        client_focus(self);
+        client_focus(self, FALSE);
     }
 }
 
@@ -3336,10 +3336,8 @@ gboolean client_can_focus(ObClient *self)
     return TRUE;
 }
 
-gboolean client_focus(ObClient *self)
+gboolean client_focus(ObClient *self, gboolean checkinvalid)
 {
-    gboolean error;
-
     /* choose the correct target */
     self = client_focus_target(self);
 
@@ -3365,8 +3363,9 @@ gboolean client_focus(ObClient *self)
     if (keyboard_interactively_grabbed())
         keyboard_interactive_cancel();
 
-    error = FALSE;
-    xerror_set_ignore(TRUE);
+    if (checkinvalid)
+        xerror_set_ignore(TRUE);
+    xerror_occured = FALSE;
 
     if (self->can_focus) {
         /* This can cause a BadMatch error with CurrentTime, or if an app
@@ -3390,13 +3389,10 @@ gboolean client_focus(ObClient *self)
         XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce);
     }
 
-    /* This calls XSync, which will cause the FocusIn to come back to us.
-       That's important for desktop switches, since otherwise we'll have no
-       FocusIn on the queue and end up falling back again. */
-    xerror_set_ignore(FALSE);
-    if (!xerror_occured) error = TRUE;
+    if (checkinvalid)
+        xerror_set_ignore(FALSE);
 
-    return !error;
+    return !xerror_occured;
 }
 
 /*! Present the client to the user.
@@ -3430,7 +3426,7 @@ static void client_present(ObClient *self, gboolean here, gboolean raise)
     if (raise)
         stacking_raise(CLIENT_AS_WINDOW(self));
 
-    client_focus(self);
+    client_focus(self, FALSE);
 }
 
 void client_activate(ObClient *self, gboolean here, gboolean user)
index 5526c282ddf6d9cc242b445206c4fa3c460d8a05..9019c62dcc863691b86e1a36ebdadee769bfeafd 100644 (file)
@@ -532,9 +532,10 @@ ObClient *client_focus_target(ObClient *self);
 gboolean client_can_focus(ObClient *self);
 
 /*! Attempt to focus the client window
-  NOTE: You should validate the client before calling this !! (client_validate)
-*/
-gboolean client_focus(ObClient *self);
+  If you care if focus actually went to the window or not, pass checkinvalid
+  as TRUE.
+ */
+gboolean client_focus(ObClient *self, gboolean checkinvalid);
 
 /*! Activates the client for use, focusing, uniconifying it, etc. To be used
   when the user deliberately selects a window for use.
index a2571f0e112dac34c82fca7e537b48b07d003b6b..9d10698b8b7dd17980108e3e14ffbec7add574fa 100644 (file)
@@ -307,10 +307,6 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only)
                 return FALSE;
         }
 
-        /* This means focus moved to the frame window */
-        if (detail == NotifyInferior && !in_client_only)
-            return TRUE;
-
         /* It was on a client, was it a valid one?
            It's possible to get a FocusIn event for a client that was managed
            but has disappeared.
@@ -351,9 +347,6 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only)
         /* This means focus moved from one client to another */
         if (detail == NotifyNonlinearVirtual)
             return TRUE;
-        /* This means focus had moved to our frame window and now moved off */
-        if (detail == NotifyNonlinear)
-            return TRUE;
 
         /* Otherwise.. */
         return FALSE;
@@ -484,9 +477,7 @@ static void event_process(const XEvent *ec, gpointer data)
         {
             XEvent ce;
 
-            ob_debug_type(OB_DEBUG_FOCUS,
-                          "Focus went to pointer root/none or to our frame "
-                          "window\n");
+            ob_debug_type(OB_DEBUG_FOCUS, "Focus went to pointer root/none\n");
 
             /* If another FocusIn is in the queue then don't fallback yet. This
                fixes the fun case of:
@@ -508,40 +499,24 @@ static void event_process(const XEvent *ec, gpointer data)
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "  but another FocusIn is coming\n");
             } else {
-                /* Focus has been reverted to the root window, nothing, or to
-                   our frame window.
+                /* Focus has been reverted to the root window or nothing.
 
                    FocusOut events come after UnmapNotify, so we don't need to
                    worry about focusing an invalid window
                 */
 
-                /* In this case we know focus is in our screen */
-                if (e->xfocus.detail == NotifyInferior)
-                    focus_left_screen = FALSE;
-
                 if (!focus_left_screen)
                     focus_fallback(TRUE);
             }
         }
         else if (!client)
         {
-            XEvent ce;
-
             ob_debug_type(OB_DEBUG_FOCUS,
                           "Focus went to a window that is already gone\n");
 
             /* If you send focus to a window and then it disappears, you can
                get the FocusIn FocusOut for it, after it is unmanaged.
-            */
-            if (XCheckIfEvent(ob_display, &ce, event_look_for_focusin_client,
-                              NULL))
-            {
-                XPutBackEvent(ob_display, &ce);
-                ob_debug_type(OB_DEBUG_FOCUS,
-                              "  but another FocusIn is coming\n");
-            } else {
-                focus_fallback(TRUE);
-            }
+               Just wait for the next FocusOut/FocusIn pair. */
         }
         else if (client != focus_client) {
             focus_left_screen = FALSE;
@@ -1718,7 +1693,7 @@ static gboolean focus_delay_func(gpointer data)
 
     event_curtime = d->time;
     if (focus_client != d->client) {
-        if (client_focus(d->client) && config_focus_raise)
+        if (client_focus(d->client, FALSE) && config_focus_raise)
             stacking_raise(CLIENT_AS_WINDOW(d->client));
     }
     event_curtime = old;
index 47c3846f0a7e8115603a0d78193f76f84a52ddd1..60e6ea99e6f4f3a58162b97041f224d207801ba6 100644 (file)
@@ -190,91 +190,86 @@ void focus_set_client(ObClient *client)
     }
 }
 
-static ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old)
+static ObClient* focus_fallback_target(gboolean allow_refocus)
 {
     GList *it;
-    ObClient *target = NULL;
-    ObClient *desktop = NULL;
+    ObClient *c;
+    ObClient *old = focus_client;
 
     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 (client_normal(target) && client_can_focus(target)) {
-                    ob_debug_type(OB_DEBUG_FOCUS, "found in pointer stuff\n");
-                    return target;
-                }
-    }
-
-#if 0
-        /* try for group relations */
-        if (old->group) {
-            GSList *sit;
-
-            for (it = focus_order[screen_desktop]; it; it = g_list_next(it))
-                for (sit = old->group->members; sit; sit = g_slist_next(sit))
-                    if (sit->data == it->data)
-                        if (sit->data != old && client_normal(sit->data))
-                            if (client_can_focus(sit->data))
-                                return sit->data;
+        if ((c = client_under_pointer()) &&
+            (allow_refocus || c != old) &&
+            (client_normal(c) &&
+             client_focus(c, TRUE)))
+        {
+            ob_debug_type(OB_DEBUG_FOCUS, "found in pointer stuff\n");
+            return c;
         }
-#endif
 
     ob_debug_type(OB_DEBUG_FOCUS, "trying omnipresentness\n");
-    if (allow_refocus && old && old->desktop == DESKTOP_ALL &&
-        client_normal(old))
+    if (allow_refocus && old &&
+        old->desktop == DESKTOP_ALL &&
+        client_normal(old) &&
+        client_focus(old, TRUE))
     {
+        ob_debug_type(OB_DEBUG_FOCUS, "found in omnipresentness\n");
         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. 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))
-            {
-                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->type == OB_CLIENT_TYPE_DESKTOP && 
-                           desktop == NULL)
-                    desktop = c;
-            }
+    for (it = focus_order; it; it = g_list_next(it)) {
+        c = it->data;
+        /* fallback focus to a window if:
+           1. it is on the current desktop. this ignores omnipresent
+           windows, which are problematic in their own rite.
+           2. 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 (c->desktop == screen_desktop &&
+            client_normal(c) &&
+            (allow_refocus || c != old) &&
+            client_focus(c, TRUE))
+        {
+            ob_debug_type(OB_DEBUG_FOCUS, "found in focus order\n");
+            return c;
         }
+    }
 
-    /* as a last resort fallback to the desktop window if there is one.
-       (if there's more than one, then the one most recently focused.)
-    */
-    ob_debug_type(OB_DEBUG_FOCUS, "found desktop: \n", !!desktop);
-    return desktop;   
+    ob_debug_type(OB_DEBUG_FOCUS, "trying a desktop window\n");
+    for (it = focus_order; it; it = g_list_next(it)) {
+        c = it->data;
+        /* fallback focus to a window if:
+           1. it is on the current desktop. this ignores omnipresent
+           windows, which are problematic in their own rite.
+           2. 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 (c->type == OB_CLIENT_TYPE_DESKTOP &&
+            (allow_refocus || c != old) &&
+            client_focus(c, TRUE))
+        {
+            ob_debug_type(OB_DEBUG_FOCUS, "found a desktop window\n");
+            return c;
+        }
+    }
+
+    return NULL;
 }
 
 ObClient* focus_fallback(gboolean allow_refocus)
 {
     ObClient *new;
-    ObClient *old;
-
-    old = focus_client;
-    new = focus_fallback_target(allow_refocus, focus_client);
 
     /* unfocus any focused clients.. they can be focused by Pointer events
        and such, and then when we try focus them, we won't get a FocusIn
        event at all for them. */
     focus_nothing();
 
-    if (new)
-        client_focus(new);
+    new = focus_fallback_target(allow_refocus);
 
     return new;
 }
index 78b5322373021c7e6267be94059a133c15089dda..419d2b55f932f65d0a3de4d52986da4c1b8e004e 100644 (file)
@@ -311,7 +311,7 @@ gint main(gint argc, gchar **argv)
                     (w = g_hash_table_lookup(window_map, &xid)) &&
                     WINDOW_IS_CLIENT(w))
                 {
-                    client_focus(WINDOW_AS_CLIENT(w));
+                    client_focus(WINDOW_AS_CLIENT(w), FALSE);
                 }
             } else {
                 GList *it;
index 452462979c663e868e5b85981908fc344b17c48f..23821301274908a349a4796f0c8fec0ebab05b09 100644 (file)
@@ -942,7 +942,7 @@ void screen_show_desktop(gboolean show, ObClient *show_only)
             ObClient *c = it->data;
             if (c->type == OB_CLIENT_TYPE_DESKTOP &&
                 (c->desktop == screen_desktop || c->desktop == DESKTOP_ALL) &&
-                client_focus(it->data))
+                client_focus(it->data, FALSE))
                 break;
         }
     }
This page took 0.04338 seconds and 4 git commands to generate.