diff options
| -rw-r--r-- | openbox/action.c | 2 | ||||
| -rw-r--r-- | openbox/client.c | 22 | ||||
| -rw-r--r-- | openbox/client.h | 7 | ||||
| -rw-r--r-- | openbox/event.c | 33 | ||||
| -rw-r--r-- | openbox/focus.c | 111 | ||||
| -rw-r--r-- | openbox/openbox.c | 2 | ||||
| -rw-r--r-- | openbox/screen.c | 2 |
7 files changed, 73 insertions, 106 deletions
diff --git a/openbox/action.c b/openbox/action.c index 3f43a238..50191859 100644 --- a/openbox/action.c +++ b/openbox/action.c @@ -1296,7 +1296,7 @@ void action_focus(union ActionData *data) go moving on us */ event_halt_focus_delay(); - client_focus(data->client.any.c); + client_focus(data->client.any.c, FALSE); } } else { /* focus action on something other than a client, make keybindings diff --git a/openbox/client.c b/openbox/client.c index 837dd019..fa4aae95 100644 --- a/openbox/client.c +++ b/openbox/client.c @@ -2842,7 +2842,7 @@ void client_fullscreen(ObClient *self, gboolean fs) if (fs) { /* try focus us when we go into fullscreen mode */ - client_focus(self); + client_focus(self, FALSE); } } @@ -3336,10 +3336,8 @@ gboolean client_can_focus(ObClient *self) return TRUE; } -gboolean client_focus(ObClient *self) +gboolean client_focus(ObClient *self, gboolean checkinvalid) { - gboolean error; - /* choose the correct target */ self = client_focus_target(self); @@ -3365,8 +3363,9 @@ gboolean client_focus(ObClient *self) if (keyboard_interactively_grabbed()) keyboard_interactive_cancel(); - error = FALSE; - xerror_set_ignore(TRUE); + if (checkinvalid) + xerror_set_ignore(TRUE); + xerror_occured = FALSE; if (self->can_focus) { /* This can cause a BadMatch error with CurrentTime, or if an app @@ -3390,13 +3389,10 @@ gboolean client_focus(ObClient *self) XSendEvent(ob_display, self->window, FALSE, NoEventMask, &ce); } - /* This calls XSync, which will cause the FocusIn to come back to us. - That's important for desktop switches, since otherwise we'll have no - FocusIn on the queue and end up falling back again. */ - xerror_set_ignore(FALSE); - if (!xerror_occured) error = TRUE; + if (checkinvalid) + xerror_set_ignore(FALSE); - return !error; + return !xerror_occured; } /*! Present the client to the user. @@ -3430,7 +3426,7 @@ static void client_present(ObClient *self, gboolean here, gboolean raise) if (raise) stacking_raise(CLIENT_AS_WINDOW(self)); - client_focus(self); + client_focus(self, FALSE); } void client_activate(ObClient *self, gboolean here, gboolean user) diff --git a/openbox/client.h b/openbox/client.h index 5526c282..9019c62d 100644 --- a/openbox/client.h +++ b/openbox/client.h @@ -532,9 +532,10 @@ ObClient *client_focus_target(ObClient *self); gboolean client_can_focus(ObClient *self); /*! Attempt to focus the client window - NOTE: You should validate the client before calling this !! (client_validate) -*/ -gboolean client_focus(ObClient *self); + If you care if focus actually went to the window or not, pass checkinvalid + as TRUE. + */ +gboolean client_focus(ObClient *self, gboolean checkinvalid); /*! Activates the client for use, focusing, uniconifying it, etc. To be used when the user deliberately selects a window for use. diff --git a/openbox/event.c b/openbox/event.c index a2571f0e..9d10698b 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -307,10 +307,6 @@ static gboolean wanted_focusevent(XEvent *e, gboolean in_client_only) 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. @@ -351,9 +347,6 @@ 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; @@ -484,9 +477,7 @@ static void event_process(const XEvent *ec, gpointer data) { 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: @@ -508,40 +499,24 @@ static void event_process(const XEvent *ec, gpointer data) 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) { - XEvent ce; - 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 FocusOut for it, after it is unmanaged. - */ - 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_fallback(TRUE); - } + Just wait for the next FocusOut/FocusIn pair. */ } else if (client != focus_client) { focus_left_screen = FALSE; @@ -1718,7 +1693,7 @@ static gboolean focus_delay_func(gpointer data) event_curtime = d->time; if (focus_client != d->client) { - if (client_focus(d->client) && config_focus_raise) + if (client_focus(d->client, FALSE) && config_focus_raise) stacking_raise(CLIENT_AS_WINDOW(d->client)); } event_curtime = old; diff --git a/openbox/focus.c b/openbox/focus.c index 47c3846f..60e6ea99 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -190,91 +190,86 @@ void focus_set_client(ObClient *client) } } -static ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old) +static ObClient* focus_fallback_target(gboolean allow_refocus) { GList *it; - ObClient *target = NULL; - ObClient *desktop = NULL; + ObClient *c; + ObClient *old = focus_client; ob_debug_type(OB_DEBUG_FOCUS, "trying pointer stuff\n"); if (config_focus_follow && !config_focus_last) - { - if ((target = client_under_pointer())) - if (allow_refocus || target != old) - if (client_normal(target) && client_can_focus(target)) { - ob_debug_type(OB_DEBUG_FOCUS, "found in pointer stuff\n"); - return target; - } - } - -#if 0 - /* try for group relations */ - if (old->group) { - GSList *sit; - - for (it = focus_order[screen_desktop]; it; it = g_list_next(it)) - for (sit = old->group->members; sit; sit = g_slist_next(sit)) - if (sit->data == it->data) - if (sit->data != old && client_normal(sit->data)) - if (client_can_focus(sit->data)) - return sit->data; + if ((c = client_under_pointer()) && + (allow_refocus || c != old) && + (client_normal(c) && + client_focus(c, TRUE))) + { + ob_debug_type(OB_DEBUG_FOCUS, "found in pointer stuff\n"); + return c; } -#endif ob_debug_type(OB_DEBUG_FOCUS, "trying omnipresentness\n"); - if (allow_refocus && old && old->desktop == DESKTOP_ALL && - client_normal(old)) + if (allow_refocus && old && + old->desktop == DESKTOP_ALL && + client_normal(old) && + client_focus(old, TRUE)) { + ob_debug_type(OB_DEBUG_FOCUS, "found in omnipresentness\n"); return old; } ob_debug_type(OB_DEBUG_FOCUS, "trying the focus order\n"); - for (it = focus_order; it; it = g_list_next(it)) - if (allow_refocus || it->data != old) { - ObClient *c = it->data; - /* fallback focus to a window if: - 1. it is actually focusable, cuz if it's not then we're sending - focus off to nothing. this includes if it is visible right now - 2. it is on the current desktop. this ignores omnipresent - windows, which are problematic in their own rite. - 3. it is a normal type window, don't fall back onto a dock or - a splashscreen or a desktop window (save the desktop as a - backup fallback though) - */ - if (client_can_focus(c)) - { - if (c->desktop == screen_desktop && client_normal(c)) { - ob_debug_type(OB_DEBUG_FOCUS, "found in focus order\n"); - return it->data; - } else if (c->type == OB_CLIENT_TYPE_DESKTOP && - desktop == NULL) - desktop = c; - } + for (it = focus_order; it; it = g_list_next(it)) { + c = it->data; + /* fallback focus to a window if: + 1. it is on the current desktop. this ignores omnipresent + windows, which are problematic in their own rite. + 2. it is a normal type window, don't fall back onto a dock or + a splashscreen or a desktop window (save the desktop as a + backup fallback though) + */ + if (c->desktop == screen_desktop && + client_normal(c) && + (allow_refocus || c != old) && + client_focus(c, TRUE)) + { + ob_debug_type(OB_DEBUG_FOCUS, "found in focus order\n"); + return c; } + } - /* as a last resort fallback to the desktop window if there is one. - (if there's more than one, then the one most recently focused.) - */ - ob_debug_type(OB_DEBUG_FOCUS, "found desktop: \n", !!desktop); - return desktop; + ob_debug_type(OB_DEBUG_FOCUS, "trying a desktop window\n"); + for (it = focus_order; it; it = g_list_next(it)) { + c = it->data; + /* fallback focus to a window if: + 1. it is on the current desktop. this ignores omnipresent + windows, which are problematic in their own rite. + 2. it is a normal type window, don't fall back onto a dock or + a splashscreen or a desktop window (save the desktop as a + backup fallback though) + */ + if (c->type == OB_CLIENT_TYPE_DESKTOP && + (allow_refocus || c != old) && + client_focus(c, TRUE)) + { + ob_debug_type(OB_DEBUG_FOCUS, "found a desktop window\n"); + return c; + } + } + + return NULL; } ObClient* focus_fallback(gboolean allow_refocus) { ObClient *new; - ObClient *old; - - old = focus_client; - new = focus_fallback_target(allow_refocus, focus_client); /* unfocus any focused clients.. they can be focused by Pointer events and such, and then when we try focus them, we won't get a FocusIn event at all for them. */ focus_nothing(); - if (new) - client_focus(new); + new = focus_fallback_target(allow_refocus); return new; } diff --git a/openbox/openbox.c b/openbox/openbox.c index 78b53223..419d2b55 100644 --- a/openbox/openbox.c +++ b/openbox/openbox.c @@ -311,7 +311,7 @@ gint main(gint argc, gchar **argv) (w = g_hash_table_lookup(window_map, &xid)) && WINDOW_IS_CLIENT(w)) { - client_focus(WINDOW_AS_CLIENT(w)); + client_focus(WINDOW_AS_CLIENT(w), FALSE); } } else { GList *it; diff --git a/openbox/screen.c b/openbox/screen.c index 45246297..23821301 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -942,7 +942,7 @@ void screen_show_desktop(gboolean show, ObClient *show_only) ObClient *c = it->data; if (c->type == OB_CLIENT_TYPE_DESKTOP && (c->desktop == screen_desktop || c->desktop == DESKTOP_ALL) && - client_focus(it->data)) + client_focus(it->data, FALSE)) break; } } |
