all repos — openbox @ 361bf6af5c7de09f30f3cf4a220b3f84a3fe451d

openbox fork - make it a bit more like ryudo

simplify focus handling a bit. no need to listen to focus going to the frame because if it ever does that, the window is unmapping and the frame will just unmap and send it to root.

make focus fallback a lil more robust, it checks for errors when it sets focus on the window, and if an error occured it will focus the next option.
Dana Jansens danakj@orodu.net
commit

361bf6af5c7de09f30f3cf4a220b3f84a3fe451d

parent

f5597c060e0fda3b8fffc19c9b8974dde463a962

M openbox/action.copenbox/action.c

@@ -1296,7 +1296,7 @@ /* if using focus_delay, stop the timer now so that focus doesn't

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
M openbox/client.copenbox/client.c

@@ -2842,7 +2842,7 @@ client_calc_layer(self);

if (fs) { /* try focus us when we go into fullscreen mode */ - client_focus(self); + client_focus(self, FALSE); } }

@@ -3336,10 +3336,8 @@

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 @@ */

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 @@ ce.xclient.data.l[4] = 0l;

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 @@ client_shade(self, FALSE);

if (raise) stacking_raise(CLIENT_AS_WINDOW(self)); - client_focus(self); + client_focus(self, FALSE); } void client_activate(ObClient *self, gboolean here, gboolean user)
M openbox/client.hopenbox/client.h

@@ -532,9 +532,10 @@ without focusing it or modifying the focus order lists. */

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.
M openbox/event.copenbox/event.c

@@ -307,10 +307,6 @@ 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.

@@ -350,9 +346,6 @@ if (detail == NotifyVirtual)

return TRUE; /* 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.. */

@@ -484,9 +477,7 @@ 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:

@@ -508,40 +499,24 @@ 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) { - 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 @@ Time old = event_curtime;

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;
M openbox/focus.copenbox/focus.c

@@ -190,91 +190,86 @@ net_active_window, window, active);

} } -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; + } + } + + 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; } + } - /* 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; + 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; }
M openbox/openbox.copenbox/openbox.c

@@ -311,7 +311,7 @@ net_active_window, window, &xid) &&

(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;
M openbox/screen.copenbox/screen.c

@@ -942,7 +942,7 @@ for (it = focus_order; it; it = g_list_next(it)) {

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; } }