From a70633d42af849e4de2288ec48fa6abe726a484e Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sun, 22 Apr 2007 13:53:28 +0000 Subject: [PATCH] eat enter events after unmanaging a window change how focus falls back for windows being unmanaged, don't fall back immediately, instead wait for the focus out event and use it (break stuff maybe! yay) --- openbox/client.c | 36 +++------------- openbox/event.c | 108 ++++++++++++++++++++++++----------------------- 2 files changed, 61 insertions(+), 83 deletions(-) diff --git a/openbox/client.c b/openbox/client.c index e801ac18..e7af5701 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -77,7 +77,6 @@ static void client_apply_startup_state(ObClient *self, gint x, gint y); static void client_restore_session_state(ObClient *self); static void client_restore_session_stacking(ObClient *self); static ObAppSettings *client_get_settings_state(ObClient *self); -static void client_unfocus(ObClient *self); void client_startup(gboolean reconfig) { @@ -507,8 +506,8 @@ void client_unmanage(ObClient *self) g_assert(self != NULL); - /* update the focus lists */ - focus_order_remove(self); + frame_hide(self->frame); + XSync(ob_display, FALSE); if (focus_client == self) { XEvent e; @@ -516,20 +515,8 @@ void client_unmanage(ObClient *self) /* focus the last focused window on the desktop, and ignore enter events from the unmap so it doesnt mess with the focus */ while (XCheckTypedEvent(ob_display, EnterNotify, &e)); - /* remove these flags so we don't end up getting focused in the - fallback! */ - self->can_focus = FALSE; - self->focus_notify = FALSE; - self->modal = FALSE; - client_unfocus(self); } - /* potentially fix focusLast */ - if (config_focus_last) - grab_pointer(TRUE, OB_CURSOR_NONE); - - frame_hide(self->frame); - XFlush(ob_display); keyboard_grab_for_client(self, FALSE); mouse_grab_for_client(self, FALSE); @@ -540,6 +527,9 @@ void client_unmanage(ObClient *self) /* we dont want events no more */ XSelectInput(ob_display, self->window, NoEventMask); + /* update the focus lists */ + focus_order_remove(self); + client_list = g_list_remove(client_list, self); stacking_remove(self); g_hash_table_remove(window_map, &self->window); @@ -639,9 +629,6 @@ void client_unmanage(ObClient *self) /* update the list hints */ client_set_list(); - - if (config_focus_last) - grab_pointer(FALSE, OB_CURSOR_NONE); } static ObAppSettings *client_get_settings_state(ObClient *self) @@ -3054,19 +3041,6 @@ gboolean client_focus(ObClient *self) return TRUE; } -/* Used when the current client is closed or otherwise hidden, focus_last will - then prevent focus from going to the mouse pointer -*/ -static void client_unfocus(ObClient *self) -{ - if (focus_client == self) { -#ifdef DEBUG_FOCUS - ob_debug("client_unfocus for %lx\n", self->window); -#endif - focus_fallback(FALSE); - } -} - void client_activate(ObClient *self, gboolean here, gboolean user) { guint32 last_time = focus_client ? focus_client->user_time : CurrentTime; diff --git a/openbox/event.c b/openbox/event.c index 9a1e13dc..4d74284b 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -398,12 +398,11 @@ static gboolean event_ignore(XEvent *e, ObClient *client) return keyboard_interactively_grabbed(); case FocusIn: case FocusOut: - /* I don't think this should ever happen with our event masks, but - if it does, we don't want it. */ - if (client == NULL) - return TRUE; - if (!wanted_focusevent(e)) + if (!wanted_focusevent(e)) { + ob_debug_type(OB_DEBUG_FOCUS, "focus event ignored\n"); return TRUE; + } + ob_debug_type(OB_DEBUG_FOCUS, "focus event used;\n"); break; } return FALSE; @@ -485,6 +484,58 @@ static void event_process(const XEvent *ec, gpointer data) { /* crossing events for menu */ event_handle_menu(e); + } else if (e->type == FocusIn) { + if (e->xfocus.detail == NotifyPointerRoot || + e->xfocus.detail == NotifyDetailNone) { + ob_debug_type(OB_DEBUG_FOCUS, "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 (e->xfocus.detail == NotifyInferior) { + ob_debug_type(OB_DEBUG_FOCUS, "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 if (client && client != focus_client) { + focus_set_client(client); + frame_adjust_focus(client->frame, TRUE); + client_calc_layer(client); + } + } else if (e->type == FocusOut) { + gboolean nomove = FALSE; + XEvent ce; + + ob_debug_type(OB_DEBUG_FOCUS, "FocusOut Event\n"); + + /* 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, or a window on another screen. */ + ob_debug_type(OB_DEBUG_FOCUS, "Focus went to a black hole !\n"); + } else if (ce.xany.window == e->xany.window) { + /* If focus didn't actually move anywhere, there is nothing to do*/ + nomove = TRUE; + } else { + /* Focus did move, so process the FocusIn event */ + ObEventData ed = { .ignored = FALSE }; + event_process(&ce, &ed); + if (ed.ignored) { + /* The FocusIn was ignored, this means it was on a window + that isn't a client. */ + ob_debug_type(OB_DEBUG_FOCUS, + "Focus went to an unmanaged window 0x%x !\n", + ce.xfocus.window); + focus_fallback(TRUE); + } + } + + if (client && !nomove) { + /* This client is no longer focused, so show that */ + focus_hilite = NULL; + frame_adjust_focus(client->frame, FALSE); + client_calc_layer(client); + } } else if (group) event_handle_group(group, e); else if (client) @@ -690,53 +741,6 @@ static void event_handle_client(ObClient *client, XEvent *e) } } break; - case FocusIn: - if (client != focus_client) { - focus_set_client(client); - frame_adjust_focus(client->frame, TRUE); - client_calc_layer(client); - } - break; - case FocusOut: - /* 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, or a window on another screen. */ - ob_debug_type(OB_DEBUG_FOCUS, "Focus went to a black hole !\n"); - } 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_type(OB_DEBUG_FOCUS, "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_type(OB_DEBUG_FOCUS, "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 = { .ignored = FALSE }; - event_process(&ce, &ed); - if (ed.ignored) { - /* The FocusIn was ignored, this means it was on a window - that isn't a client. */ - ob_debug_type(OB_DEBUG_FOCUS, - "Focus went to an unmanaged window 0x%x !\n", - ce.xfocus.window); - focus_fallback(TRUE); - } - } - - /* This client is no longer focused, so show that */ - focus_hilite = NULL; - frame_adjust_focus(client->frame, FALSE); - client_calc_layer(client); - break; case LeaveNotify: con = frame_context(client, e->xcrossing.window); switch (con) { -- 2.39.2