X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=a2571f0e112dac34c82fca7e537b48b07d003b6b;hb=47c8d407295bd910b2482f472d0a7e3892031647;hp=9e72408db951a40cc9f381b4541ce0c49036e620;hpb=2fdad9a0ff8f0f379a0f4dca8f25895bb5b49d0f;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index 9e72408d..a2571f0e 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -307,15 +307,26 @@ 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. + */ + 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; @@ -356,13 +367,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 +394,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,6 +483,7 @@ 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"); @@ -514,16 +523,25 @@ static void event_process(const XEvent *ec, gpointer data) 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) + { + XEvent ce; + + 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. + /* If you send focus to a window and then it disappears, you can + get the FocusIn FocusOut for it, after it is unmanaged. */ - ob_debug_type(OB_DEBUG_FOCUS, "Focus went to an invalid target\n"); - focus_set_client(NULL); + 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); + } } else if (client != focus_client) { focus_left_screen = FALSE; @@ -578,6 +596,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 +706,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)