From 2f8d827147a02e8599e9e27593477e23ef64aa09 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Fri, 4 May 2007 02:48:56 +0000 Subject: [PATCH] merge r6016-6018 from trunk --- openbox/client.c | 51 ++++++++++++++++++++++-------------------------- openbox/event.c | 45 +++++++++++++++++++++++++++++++----------- 2 files changed, 57 insertions(+), 39 deletions(-) diff --git a/openbox/client.c b/openbox/client.c index c7859ca6..df0102c7 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -381,8 +381,10 @@ void client_manage(Window window) focus_client->user_time : CurrentTime; /* This is focus stealing prevention */ - ob_debug("Want to focus new window 0x%x with time %u (last time %u)\n", - self->window, self->user_time, last_time); + ob_debug_type(OB_DEBUG_FOCUS, + "Want to focus new window 0x%x with time %u " + "(last time %u)\n", + self->window, self->user_time, last_time); /* if it's on another desktop */ if (!(self->desktop == screen_desktop || self->desktop == DESKTOP_ALL) @@ -391,31 +393,38 @@ void client_manage(Window window) !event_time_after(self->user_time, screen_desktop_user_time)) { activate = FALSE; + ob_debug_type(OB_DEBUG_FOCUS, + "Not focusing the window because its on another " + "desktop\n"); } - /* If nothing is focused, or a parent was focused, then focus this - always - */ - else if (!focus_client || client_search_focus_parent(self) != NULL) - activate = TRUE; - else + /* If something is focused, and it's not our parent... */ + else if (focus_client && client_search_focus_parent(self) == NULL) { /* If time stamp is old, don't steal focus */ if (self->user_time && last_time && !event_time_after(self->user_time, last_time)) { activate = FALSE; + ob_debug_type(OB_DEBUG_FOCUS, + "Not focusing the window because the time is " + "too old\n"); } /* Don't steal focus from globally active clients. I stole this idea from KWin. It seems nice. */ - if (!(focus_client->can_focus || focus_client->focus_notify)) + if (!(focus_client->can_focus || focus_client->focus_notify)) { activate = FALSE; + ob_debug_type(OB_DEBUG_FOCUS, + "Not focusing the window because a globally " + "active client has focus\n"); + } } if (!activate) { - ob_debug("Focus stealing prevention activated for %s with time %u " - "(last time %u)\n", - self->title, self->user_time, last_time); + ob_debug_type(OB_DEBUG_FOCUS, + "Focus stealing prevention activated for %s with " + "time %u (last time %u)\n", + self->title, self->user_time, last_time); /* if the client isn't focused, then hilite it so the user knows it is there */ client_hilite(self, TRUE); @@ -494,22 +503,8 @@ void client_unmanage(ObClient *self) /* update the focus lists */ focus_order_remove(self); if (client_focused(self)) { - /* we have to fall back here because we might not get a focus out. - 1. we need to xselectinput off the window before we unmap it because - otherwise we end up getting unmapnotifies we don't want and they - can mess up mapping it again quickly - 2. this means that if we unmanage from a synthetic unmapnotify, we - are the ones unmapped it, and causing the focusout. so we won't - get the focusout event. - 3. we can't handle focusin events on the root window because they - come from all screens, so the focus change gets lost - - if this ever gets removed in the future MAKE SURE to replace it - with: - /- don't leave an invalid focus_client -/ - focus_client = NULL; - */ - focus_fallback(FALSE); + /* don't leave an invalid focus_client */ + focus_client = NULL; } client_list = g_list_remove(client_list, self); diff --git a/openbox/event.c b/openbox/event.c index d4ac2176..ff9ea574 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -96,6 +96,7 @@ Time event_curtime = CurrentTime; static guint ignore_enter_focus = 0; static gboolean menu_can_hide; +static gboolean focus_left_screen = FALSE; #ifdef USE_SM static void ice_handler(gint fd, gpointer conn) @@ -415,7 +416,23 @@ static void event_process(const XEvent *ec, gpointer data) /* crossing events for menu */ event_handle_menu(e); } else if (e->type == FocusIn) { - if (client && client != focus_client) { + if (e->xfocus.detail == NotifyPointerRoot || + e->xfocus.detail == NotifyDetailNone) + { + ob_debug_type(OB_DEBUG_FOCUS, "Focus went to pointer root/none\n"); + /* 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 + */ + if (!focus_left_screen) + focus_fallback(TRUE); + } else if (e->xfocus.detail == NotifyInferior) { + ob_debug_type(OB_DEBUG_FOCUS, + "Focus went to root or our frame window"); + /* Focus has been given to the root window. */ + focus_fallback(TRUE); + } else if (client && client != focus_client) { + focus_left_screen = FALSE; frame_adjust_focus(client->frame, TRUE); focus_set_client(client); client_calc_layer(client); @@ -430,22 +447,28 @@ static void event_process(const XEvent *ec, gpointer data) 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"); + Window win, root; + gint i; + guint u; + xerror_set_ignore(TRUE); + if (XGetInputFocus(ob_display, &win, &i) != 0 && + XGetGeometry(ob_display, win, &root, &i,&i,&u,&u,&u,&u) != 0 && + root != RootWindow(ob_display, ob_screen)) + { + ob_debug_type(OB_DEBUG_FOCUS, + "Focus went to another screen !\n"); + focus_left_screen = TRUE; + } + else + ob_debug_type(OB_DEBUG_FOCUS, + "Focus went to a black hole !\n"); + xerror_set_ignore(FALSE); /* nothing is focused */ focus_set_client(NULL); } else if (ce.xany.window == e->xany.window) { ob_debug_type(OB_DEBUG_FOCUS, "Focus didn't go anywhere\n"); /* If focus didn't actually move anywhere, there is nothing to do*/ nomove = TRUE; - } else if (ce.xfocus.detail == NotifyPointerRoot || - ce.xfocus.detail == NotifyDetailNone || - ce.xfocus.detail == NotifyInferior) { - ob_debug_type(OB_DEBUG_FOCUS, "Focus went to root\n"); - /* 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 - */ - focus_fallback(TRUE); } else { /* Focus did move, so process the FocusIn event */ ObEventData ed = { .ignored = FALSE }; -- 2.34.1