X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;ds=sidebyside;f=openbox%2Fevent.c;h=b1e61f77c839bedcd71b77fdb216de292385623b;hb=d30809e5faf681a00035d9913a762f25db8de6b5;hp=c07148829e99d3a76fa1dbf77769669489354221;hpb=58788b9c16016fec3c50d7785d5a5282141bd0ec;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index c0714882..b1e61f77 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -131,7 +131,7 @@ void event_startup(gboolean reconfig) IceAddConnectionWatch(ice_watch, NULL); #endif - client_add_destructor(focus_delay_client_dest, NULL); + client_add_destroy_notify(focus_delay_client_dest, NULL); } void event_shutdown(gboolean reconfig) @@ -142,7 +142,7 @@ void event_shutdown(gboolean reconfig) IceRemoveConnectionWatch(ice_watch, NULL); #endif - client_remove_destructor(focus_delay_client_dest); + client_remove_destroy_notify(focus_delay_client_dest); } static Window event_get_window(XEvent *e) @@ -293,24 +293,36 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only) /* These are the ones we want.. */ - if (win == RootWindow(ob_display, ob_screen) && !in_client_only) { + if (win == RootWindow(ob_display, ob_screen)) { + /* If looking for a focus in on a client, then always return + FALSE for focus in's to the root window */ + if (in_client_only) + return FALSE; /* This means focus reverted off of a client */ - if (detail == NotifyPointerRoot || detail == NotifyDetailNone || - detail == NotifyInferior) + else if (detail == NotifyPointerRoot || + detail == NotifyDetailNone || + detail == NotifyInferior) return TRUE; else return FALSE; } + /* 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; @@ -335,21 +347,18 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only) /* This means focus moved from one client to another */ if (detail == NotifyNonlinearVirtual) return TRUE; - /* This means focus had moved to our frame window and now moved off */ - if (detail == NotifyNonlinear) - return TRUE; /* Otherwise.. */ return FALSE; } } -static Bool look_for_focusin(Display *d, XEvent *e, XPointer arg) +static Bool event_look_for_focusin(Display *d, XEvent *e, XPointer arg) { return e->type == FocusIn && wanted_focusevent(e, FALSE); } -static Bool look_for_focusin_client(Display *d, XEvent *e, XPointer arg) +Bool event_look_for_focusin_client(Display *d, XEvent *e, XPointer arg) { return e->type == FocusIn && wanted_focusevent(e, TRUE); } @@ -378,6 +387,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", @@ -464,9 +476,8 @@ 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"); + + ob_debug_type(OB_DEBUG_FOCUS, "Focus went to pointer root/none\n"); /* If another FocusIn is in the queue then don't fallback yet. This fixes the fun case of: @@ -481,26 +492,33 @@ static void event_process(const XEvent *ec, gpointer data) But if the other focus in is something like PointerRoot then we still want to fall back. */ - if (XCheckIfEvent(ob_display, &ce, look_for_focusin_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 has been reverted to the root window, nothing, or to - our frame window. + /* Focus has been reverted to the root window or nothing. FocusOut events come after UnmapNotify, so we don't need to worry about focusing an invalid window */ - /* In this case we know focus is in our screen */ - if (e->xfocus.detail == NotifyInferior) - focus_left_screen = FALSE; - if (!focus_left_screen) focus_fallback(TRUE); } - } else if (client && client != focus_client) { + } + else if (!client) + { + ob_debug_type(OB_DEBUG_FOCUS, + "Focus went to a window that is already gone\n"); + + /* If you send focus to a window and then it disappears, you can + get the FocusIn for it, after it is unmanaged. + Just wait for the next FocusOut/FocusIn pair. */ + } + else if (client != focus_client) { focus_left_screen = FALSE; frame_adjust_focus(client->frame, TRUE); focus_set_client(client); @@ -512,7 +530,7 @@ static void event_process(const XEvent *ec, gpointer data) XEvent ce; /* Look for the followup FocusIn */ - if (!XCheckIfEvent(ob_display, &ce, look_for_focusin, NULL)) { + if (!XCheckIfEvent(ob_display, &ce, event_look_for_focusin, NULL)) { /* There is no FocusIn, this means focus went to a window that is not being managed, or a window on another screen. */ Window win, root; @@ -553,6 +571,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); } @@ -661,7 +681,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) @@ -1591,6 +1611,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)))