X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=eac312df66f09d4e3eb989c90e41c6c7fa42af6e;hb=d59f0d67b0a6f3a7eed2753875691e78c08c632c;hp=c07148829e99d3a76fa1dbf77769669489354221;hpb=58788b9c16016fec3c50d7785d5a5282141bd0ec;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index c0714882..eac312df 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -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)))