X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;ds=sidebyside;f=openbox%2Fevent.c;h=e431e8f40972c47fdaad81c12f26b65b8fb63d6c;hb=7fddf2abc2b76e511be8fc14e22c1f310efe00ef;hp=86ea467c8a70ac9070037d6a6d9404fda7ff956f;hpb=1d6c07c24be25b2de4d36dfb0cc6e5f2d3518bf8;p=chaz%2Fopenbox diff --git a/openbox/event.c b/openbox/event.c index 86ea467c..e431e8f4 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -98,7 +98,6 @@ Time event_curtime = CurrentTime; static guint ignore_enter_focus = 0; static gboolean menu_can_hide; static gboolean focus_left_screen = FALSE; -static ObClient *focus_tried = NULL; #ifdef USE_SM static void ice_handler(gint fd, gpointer conn) @@ -132,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) @@ -143,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) @@ -294,24 +293,40 @@ 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; } + /* 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. Don't even parse those FocusIn events. + */ + { + 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; @@ -345,12 +360,12 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only) } } -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); } @@ -465,6 +480,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"); @@ -482,7 +498,9 @@ 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"); @@ -499,23 +517,22 @@ static void event_process(const XEvent *ec, gpointer data) focus_left_screen = FALSE; if (!focus_left_screen) - focus_tried = focus_fallback(TRUE); + focus_fallback(TRUE); } - } else if (client && client != focus_client) { + } + else if (client != focus_client) { focus_left_screen = FALSE; frame_adjust_focus(client->frame, TRUE); 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; 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; @@ -550,7 +567,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_tried = focus_fallback(TRUE); + focus_fallback(TRUE); } } @@ -1078,24 +1095,10 @@ 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 but it " - "is being unmanaged. 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 but it " - "is being unmanaged. 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 */ @@ -1114,13 +1117,6 @@ 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 but it " - "is being unmanaged. Falling back focus again.\n"); - focus_tried = focus_fallback(TRUE); - } break; case MapRequest: ob_debug("MapRequest for 0x%lx\n", client->window); @@ -1615,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)))