]> Dogcows Code - chaz/openbox/blobdiff - openbox/event.c
simplify focus handling a bit. no need to listen to focus going to the frame because...
[chaz/openbox] / openbox / event.c
index 9e72408db951a40cc9f381b4541ce0c49036e620..9d10698b8b7dd17980108e3e14ffbec7add574fa 100644 (file)
@@ -307,15 +307,22 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only)
                 return FALSE;
         }
 
+        /* 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.
+        */
+        if (in_client_only) {
+            ObWindow *w = g_hash_table_lookup(window_map, &e->xfocus.window);
+            if (!w || !WINDOW_IS_CLIENT(w))
+                return FALSE;
+        }
+
         /* This means focus moved from the root window to a client */
         if (detail == NotifyVirtual)
             return TRUE;
         /* This means focus moved from one client to another */
         if (detail == NotifyNonlinearVirtual)
             return TRUE;
-        /* This means focus moved to the frame window */
-        if (detail == NotifyInferior && !in_client_only)
-            return TRUE;
 
         /* Otherwise.. */
         return FALSE;
@@ -340,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;
@@ -356,13 +360,7 @@ static Bool event_look_for_focusin(Display *d, XEvent *e, XPointer arg)
 
 Bool event_look_for_focusin_client(Display *d, XEvent *e, XPointer arg)
 {
-    ObWindow *w;
-
-    /* It is possible to get FocusIn events or unmanaged windows, meaning
-       they won't be for any known client */
-    return e->type == FocusIn && wanted_focusevent(e, TRUE) &&
-        (w = g_hash_table_lookup(window_map, &e->xfocus.window)) &&
-        WINDOW_IS_CLIENT(w);
+    return e->type == FocusIn && wanted_focusevent(e, TRUE);
 }
 
 static void print_focusevent(XEvent *e)
@@ -389,6 +387,9 @@ static void print_focusevent(XEvent *e)
     case NotifyDetailNone:  detailstr="NotifyDetailNone";  break;
     }
 
+    if (mode == NotifyGrab || mode == NotifyUngrab)
+        return;
+
     g_assert(modestr);
     g_assert(detailstr);
     ob_debug_type(OB_DEBUG_FOCUS, "Focus%s 0x%x mode=%s detail=%s\n",
@@ -475,9 +476,8 @@ static void event_process(const XEvent *ec, gpointer data)
             e->xfocus.detail == NotifyInferior)
         {
             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:
@@ -499,31 +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) {
-            /* It is possible to get FocusIn events or unmanaged windows,
-               meaning they won't be for any known client
+        else if (!client)
+        {
+            ob_debug_type(OB_DEBUG_FOCUS,
+                          "Focus went to a window that is already gone\n");
 
-               If this happens, set the client to NULL so we know focus
-               has wandered off, and we'll get a focus out for it
-               shortly.
-            */
-            ob_debug_type(OB_DEBUG_FOCUS, "Focus went to an invalid target\n");
-            focus_set_client(NULL);
+            /* If you send focus to a window and then it disappears, you can
+               get the FocusIn FocusOut for it, after it is unmanaged.
+               Just wait for the next FocusOut/FocusIn pair. */
         }
         else if (client != focus_client) {
             focus_left_screen = FALSE;
@@ -578,6 +571,8 @@ static void event_process(const XEvent *ec, gpointer data)
 
         if (client && !nomove) {
             frame_adjust_focus(client->frame, FALSE);
+            if (client == focus_client)
+                focus_set_client(NULL);
             /* focus_set_client has already been called for sure */
             client_calc_layer(client);
         }
@@ -686,7 +681,7 @@ static void event_handle_root(XEvent *e)
                 screen_set_num_desktops(d);
         } else if (msgtype == prop_atoms.net_showing_desktop) {
             screen_show_desktop(e->xclient.data.l[0] != 0, NULL);
-        } else if (msgtype == prop_atoms.openbox_control) {
+        } else if (msgtype == prop_atoms.ob_control) {
             if (e->xclient.data.l[0] == 1)
                 ob_reconfigure();
             else if (e->xclient.data.l[0] == 2)
@@ -1698,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;
This page took 0.025911 seconds and 4 git commands to generate.