X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fevent.c;h=3aa91c618ffbb14cb667a6434c3ea4b459f55e94;hb=6372bd7c0d68793c2371ce7b6c1aa8017f913aee;hp=effa166a0d5198fab6217bf117e4ae8459e20ee2;hpb=fb3d2033ba5c9edc198296793dde59341577b9b0;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index effa166a..3aa91c61 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -312,6 +312,7 @@ static gboolean wanted_focusevent(XEvent *e) { gint mode = e->xfocus.mode; gint detail = e->xfocus.detail; + Window win = e->xany.window; if (e->type == FocusIn) { @@ -326,6 +327,15 @@ static gboolean wanted_focusevent(XEvent *e) /* These are the ones we want.. */ + if (win == RootWindow(ob_display, ob_screen)) { + /* This means focus reverted off of a client */ + if (detail == NotifyPointerRoot || detail == NotifyDetailNone || + detail == NotifyInferior) + return TRUE; + else + return FALSE; + } + /* This means focus moved from the root window to a client */ if (detail == NotifyVirtual) return TRUE; @@ -333,6 +343,10 @@ static gboolean wanted_focusevent(XEvent *e) if (detail == NotifyNonlinearVirtual) return TRUE; + /* This means focus reverted off of a client */ + if (detail == NotifyInferior) + return TRUE; + /* Otherwise.. */ return FALSE; } else { @@ -345,6 +359,10 @@ static gboolean wanted_focusevent(XEvent *e) if (mode == NotifyGrab) return FALSE; + /* Focus left the root window revertedto state */ + if (win == RootWindow(ob_display, ob_screen)) + return FALSE; + /* These are the ones we want.. */ /* This means focus moved from a client to the root window */ @@ -657,17 +675,26 @@ static void event_handle_client(ObClient *client, XEvent *e) /* Look for the followup FocusIn */ if (!XCheckIfEvent(ob_display, &ce, look_for_focusin, NULL)) { /* There is no FocusIn, this means focus went to a window that - is not being managed. most likely, this went to PointerRoot - or None, meaning the window is no longer around so fallback - focus, but not to that window */ + is not being managed, or a window on another screen. */ ob_debug("Focus went to a black hole !\n"); - focus_fallback(FALSE); } else if (ce.xany.window == e->xany.window) { /* If focus didn't actually move anywhere, there is nothing to do*/ break; + } else if (ce.xfocus.detail == NotifyPointerRoot || + ce.xfocus.detail == NotifyDetailNone) { + ob_debug("Focus went to root\n"); + /* Focus has been reverted to the root window or nothing, so fall + back to something other than the window which just had it. */ + focus_fallback(FALSE); + } else if (ce.xfocus.detail == NotifyInferior) { + ob_debug("Focus went to parent\n"); + /* Focus has been reverted to parent, which is our frame window, + or the root window, so fall back to something other than the + window which had it. */ + focus_fallback(FALSE); } else { /* Focus did move, so process the FocusIn event */ - ObEventData ed; + ObEventData ed = { .ignored = FALSE }; event_process(&ce, &ed); if (ed.ignored) { /* The FocusIn was ignored, this means it was on a window @@ -881,7 +908,10 @@ static void event_handle_client(ObClient *client, XEvent *e) } break; case UnmapNotify: - ob_debug("UnmapNotify for window 0x%x\n", client->window); + ob_debug("UnmapNotify for window 0x%x eventwin 0x%x sendevent %d " + "ignores left %d\n", + client->window, e->xunmap.event, e->xunmap.from_configure, + client->ignore_unmaps); if (client->ignore_unmaps) { client->ignore_unmaps--; break; @@ -907,6 +937,7 @@ static void event_handle_client(ObClient *client, XEvent *e) X server to deal with after we unmanage the window */ XPutBackEvent(ob_display, e); + ob_debug("ReparentNotify for window 0x%x\n", client->window); client_unmanage(client); break; case MapRequest: @@ -1232,10 +1263,11 @@ static void event_handle_menu(XEvent *ev) case MotionNotify: if ((f = menu_frame_under(ev->xmotion.x_root, ev->xmotion.y_root))) { - menu_frame_move_on_screen(f); if ((e = menu_entry_frame_under(ev->xmotion.x_root, - ev->xmotion.y_root))) + ev->xmotion.y_root))) { + /* XXX menu_frame_entry_move_on_screen(f); */ menu_frame_select(f, e); + } } { ObMenuFrame *a; @@ -1288,11 +1320,8 @@ static gboolean focus_delay_func(gpointer data) ObClient *c = data; if (focus_client != c) { - if (client_validate(c)) { - client_focus(c); - if (config_focus_raise) - client_raise(c); - } + if (client_focus(c) && config_focus_raise) + client_raise(c); } return FALSE; /* no repeat */ } @@ -1344,3 +1373,25 @@ void event_ignore_queued_enters() } g_slist_free(saved); } + +gboolean event_time_after(Time t1, Time t2) +{ + /* + Timestamp values wrap around (after about 49.7 days). The server, given + its current time is represented by timestamp T, always interprets + timestamps from clients by treating half of the timestamp space as being + later in time than T. + - http://tronche.com/gui/x/xlib/input/pointer-grabbing.html + */ + + /* TIME_HALF is half of the number space of a Time type variable */ +#define TIME_HALF (Time)(1 << (sizeof(Time)*8-1)) + + if (t2 >= TIME_HALF) + /* t2 is in the second half so t1 might wrap around and be smaller than + t2 */ + return t1 >= t2 || t1 < (t2 + TIME_HALF); + else + /* t2 is in the first half so t1 has to come after it */ + return t1 >= t2 && t1 < (t2 + TIME_HALF); +}