X-Git-Url: https://git.brokenzipper.com/gitweb?a=blobdiff_plain;f=openbox%2Ffocus.c;h=cac6fc7959101e8adcadd1e801dc56a96c231129;hb=aa6bedd78bcebc33ac15c79ccebd8b4f14aefd02;hp=84bd7b09a02f4de7941046ec1eef0090e489f9d0;hpb=4ae6be577de367a62b7986b9f23c14fed38dcc85;p=chaz%2Fopenbox diff --git a/openbox/focus.c b/openbox/focus.c index 84bd7b09..cac6fc79 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -42,10 +42,10 @@ ObClient *focus_cycle_target; static ObIconPopup *focus_cycle_popup; -static void focus_cycle_destructor(ObClient *c) +static void focus_cycle_destructor(ObClient *client, gpointer data) { /* end cycling if the target disappears */ - if (focus_cycle_target == c) + if (focus_cycle_target == client) focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE); } @@ -54,7 +54,7 @@ void focus_startup(gboolean reconfig) focus_cycle_popup = icon_popup_new(TRUE); if (!reconfig) { - client_add_destructor((GDestroyNotify) focus_cycle_destructor); + client_add_destructor(focus_cycle_destructor, NULL); /* start with nothing focused */ focus_set_client(NULL); @@ -68,15 +68,14 @@ void focus_shutdown(gboolean reconfig) icon_popup_free(focus_cycle_popup); if (!reconfig) { - client_remove_destructor((GDestroyNotify) focus_cycle_destructor); + client_remove_destructor(focus_cycle_destructor); for (i = 0; i < screen_num_desktops; ++i) g_list_free(focus_order[i]); g_free(focus_order); /* reset focus to root */ - XSetInputFocus(ob_display, PointerRoot, RevertToPointerRoot, - event_lasttime); + XSetInputFocus(ob_display, PointerRoot, RevertToNone, event_lasttime); } } @@ -104,8 +103,11 @@ void focus_set_client(ObClient *client) screen_install_colormap(client, TRUE); if (client == NULL) { - /* when nothing will be focused, send focus to the backup target */ - XSetInputFocus(ob_display, screen_support_win, RevertToPointerRoot, +#ifdef DEBUG_FOCUS + ob_debug("actively focusing NONWINDOW\n"); +#endif + /* when nothing will be focused, send focus to the backup target */ + XSetInputFocus(ob_display, screen_support_win, RevertToNone, event_lasttime); XSync(ob_display, FALSE); } @@ -129,15 +131,6 @@ void focus_set_client(ObClient *client) } } -static gboolean focus_under_pointer() -{ - ObClient *c; - - if ((c = client_under_pointer())) - return client_normal(c) && client_focus(c); - return FALSE; -} - /* finds the first transient that isn't 'skip' and ensure's that client_normal is true for it */ static ObClient *find_transient_recursive(ObClient *c, ObClient *top, ObClient *skip) @@ -154,44 +147,42 @@ static ObClient *find_transient_recursive(ObClient *c, ObClient *top, ObClient * return NULL; } -static gboolean focus_fallback_transient(ObClient *top, ObClient *old) +static ObClient* focus_fallback_transient(ObClient *top, ObClient *old) { ObClient *target = find_transient_recursive(top, top, old); if (!target) { /* make sure client_normal is true always */ if (!client_normal(top)) - return FALSE; + return NULL; target = top; /* no transient, keep the top */ } - return client_focus(target); + if (client_can_focus(target)) + return target; + else + return NULL; } -void focus_fallback(ObFocusFallbackType type) +ObClient* focus_fallback_target(ObFocusFallbackType type) { GList *it; ObClient *old = NULL; + ObClient *target = NULL; old = focus_client; - /* unfocus any focused clients.. they can be focused by Pointer events - and such, and then when I try focus them, I won't get a FocusIn event - at all for them. - */ - focus_set_client(NULL); - if (type == OB_FOCUS_FALLBACK_UNFOCUSING && old) { if (old->transient_for) { gboolean trans = FALSE; - if (config_focus_last || !config_focus_follow) + if (!config_focus_follow) trans = TRUE; else { - ObClient *c; - - if ((c = client_under_pointer()) && - client_search_transient(client_search_top_transient(c), - old)) + if ((target = client_under_pointer()) && + client_search_transient + (client_search_top_transient(target), old)) + { trans = TRUE; + } } /* try for transient relations */ @@ -202,20 +193,24 @@ void focus_fallback(ObFocusFallbackType type) for (sit = old->group->members; sit; sit = sit->next) if (sit->data == it->data) - if (focus_fallback_transient(sit->data, old)) - return; + if ((target = + focus_fallback_transient(sit->data, old))) + return target; } } else { - if (focus_fallback_transient(old->transient_for, old)) - return; + if ((target = + focus_fallback_transient(old->transient_for, old))) + return target; } } } } - if (!config_focus_last && config_focus_follow) - if (focus_under_pointer()) - return; + if (config_focus_follow) { + if ((target = client_under_pointer())) + if (client_normal(target) && client_can_focus(target)) + return target; + } #if 0 /* try for group relations */ @@ -226,23 +221,31 @@ void focus_fallback(ObFocusFallbackType type) for (sit = old->group->members; sit; sit = sit->next) if (sit->data == it->data) if (sit->data != old && client_normal(sit->data)) - if (client_can_focus(sit->data)) { - gboolean r = client_focus(sit->data); - assert(r); - return; - } + if (client_can_focus(sit->data)) + return sit->data; } #endif for (it = focus_order[screen_desktop]; it != NULL; it = it->next) if (type != OB_FOCUS_FALLBACK_UNFOCUSING || it->data != old) - if (client_normal(it->data) && client_can_focus(it->data)) { - gboolean r = client_focus(it->data); - assert(r); - return; - } + if (client_normal(it->data) && client_can_focus(it->data)) + return it->data; + + return NULL; +} + +void focus_fallback(ObFocusFallbackType type) +{ + ObClient *new; + + /* unfocus any focused clients.. they can be focused by Pointer events + and such, and then when I try focus them, I won't get a FocusIn event + at all for them. + */ + focus_set_client(NULL); - /* nothing to focus, and already set it to none above */ + if ((new = focus_fallback_target(type))) + client_focus(new); } static void popup_cycle(ObClient *c, gboolean show) @@ -291,7 +294,7 @@ static gboolean valid_focus_target(ObClient *ft) focus an iconic window, but we want to be able to, so we just check if the focus flags on the window allow it, and its on the current desktop */ - return (ft == client_focus_target(ft) && client_normal(ft) && + return (!ft->transients && client_normal(ft) && ((ft->can_focus || ft->focus_notify) && !ft->skip_taskbar && (ft->desktop == screen_desktop || ft->desktop == DESKTOP_ALL)));