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)
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;
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;
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);
}
}
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 */
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);
{
menu_frame_select(e->frame, NULL, FALSE);
}
+ break;
case MotionNotify:
if ((e = menu_entry_frame_under(ev->xmotion.x_root,
ev->xmotion.y_root)))