]> Dogcows Code - chaz/openbox/blobdiff - openbox/event.c
interactive actions cancel other interactive actions
[chaz/openbox] / openbox / event.c
index c07148829e99d3a76fa1dbf77769669489354221..eac312df66f09d4e3eb989c90e41c6c7fa42af6e 100644 (file)
@@ -98,6 +98,13 @@ Time event_curtime = CurrentTime;
 static guint ignore_enter_focus = 0;
 static gboolean menu_can_hide;
 static gboolean focus_left_screen = FALSE;
+/*! This variable is used for focus fallback. If we fallback to a window, we
+  set this to the window. And when focus goes somewhere after that, it will
+  be set to NULL. If between falling back to that window and something
+  getting focused, the window gets unmanaged, then if there are no incoming
+  FocusIn events, we fallback again because focus has just gotten itself lost.
+ */
+static ObClient *focus_tried = NULL;
 
 #ifdef USE_SM
 static void ice_handler(gint fd, gpointer conn)
@@ -498,7 +505,7 @@ static void event_process(const XEvent *ec, gpointer data)
                     focus_left_screen = FALSE;
 
                 if (!focus_left_screen)
-                    focus_fallback(TRUE);
+                    focus_tried = focus_fallback(TRUE);
             }
         } else if (client && client != focus_client) {
             focus_left_screen = FALSE;
@@ -506,6 +513,8 @@ static void event_process(const XEvent *ec, gpointer data)
             focus_set_client(client);
             client_calc_layer(client);
             client_bring_helper_windows(client);
+
+            focus_tried = NULL; /* focus isn't "trying" to go anywhere now */
         }
     } else if (e->type == FocusOut) {
         gboolean nomove = FALSE;
@@ -547,7 +556,7 @@ static void event_process(const XEvent *ec, gpointer data)
                 ob_debug_type(OB_DEBUG_FOCUS,
                               "Focus went to an unmanaged window 0x%x !\n",
                               ce.xfocus.window);
-                focus_fallback(TRUE);
+                focus_tried = focus_fallback(TRUE);
             }
         }
 
@@ -1075,10 +1084,40 @@ static void event_handle_client(ObClient *client, XEvent *e)
                  client->window, e->xunmap.event, e->xunmap.from_configure,
                  client->ignore_unmaps);
         client_unmanage(client);
+
+        /* we were trying to focus this window but it's gone */
+        if (client == focus_tried) {
+            ob_debug_type(OB_DEBUG_FOCUS, "Tried to focus window 0x%x and it "
+                          "is being unmanaged:\n");
+            if (XCheckIfEvent(ob_display, &ce, look_for_focusin_client, NULL)){
+                XPutBackEvent(ob_display, &ce);
+                ob_debug_type(OB_DEBUG_FOCUS,
+                              "  but another FocusIn is coming\n");
+            } else {
+                ob_debug_type(OB_DEBUG_FOCUS,
+                              "  so falling back focus again.\n");
+                focus_tried = focus_fallback(TRUE);
+            }
+        }
         break;
     case DestroyNotify:
         ob_debug("DestroyNotify for window 0x%x\n", client->window);
         client_unmanage(client);
+
+        /* we were trying to focus this window but it's gone */
+        if (client == focus_tried) {
+            ob_debug_type(OB_DEBUG_FOCUS, "Tried to focus window 0x%x and it "
+                          "is being unmanaged:\n");
+            if (XCheckIfEvent(ob_display, &ce, look_for_focusin_client, NULL)){
+                XPutBackEvent(ob_display, &ce);
+                ob_debug_type(OB_DEBUG_FOCUS,
+                              "  but another FocusIn is coming\n");
+            } else {
+                ob_debug_type(OB_DEBUG_FOCUS,
+                              "  so falling back focus again.\n");
+                focus_tried = focus_fallback(TRUE);
+            }
+        }
         break;
     case ReparentNotify:
         /* this is when the client is first taken captive in the frame */
@@ -1097,6 +1136,21 @@ static void event_handle_client(ObClient *client, XEvent *e)
      
         ob_debug("ReparentNotify for window 0x%x\n", client->window);
         client_unmanage(client);
+
+        /* we were trying to focus this window but it's gone */
+        if (client == focus_tried) {
+            ob_debug_type(OB_DEBUG_FOCUS, "Tried to focus window 0x%x and it "
+                          "is being unmanaged:\n");
+            if (XCheckIfEvent(ob_display, &ce, look_for_focusin_client, NULL)){
+                XPutBackEvent(ob_display, &ce);
+                ob_debug_type(OB_DEBUG_FOCUS,
+                              "  but another FocusIn is coming\n");
+            } else {
+                ob_debug_type(OB_DEBUG_FOCUS,
+                              "  so falling back focus again.\n");
+                focus_tried = focus_fallback(TRUE);
+            }
+        }
         break;
     case MapRequest:
         ob_debug("MapRequest for 0x%lx\n", client->window);
@@ -1591,6 +1645,7 @@ static gboolean event_handle_menu(XEvent *ev)
         {
             menu_frame_select(e->frame, NULL, FALSE);
         }
+        break;
     case MotionNotify:   
         if ((e = menu_entry_frame_under(ev->xmotion.x_root,   
                                         ev->xmotion.y_root)))
This page took 0.028026 seconds and 4 git commands to generate.