X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Ffocus.c;h=31fa0ef9b320d40cfe13f3d1d85175191bbad011;hb=86b7f4e543a918a24bf204aab355987c658522d9;hp=4be187b9a7682d8ed13a5edaee3da32dd56eed31;hpb=c80b496bf407d73bea169058abfcda44effad0dd;p=chaz%2Fopenbox diff --git a/openbox/focus.c b/openbox/focus.c index 4be187b9..31fa0ef9 100644 --- a/openbox/focus.c +++ b/openbox/focus.c @@ -37,9 +37,9 @@ #include #include -ObClient *focus_client, *focus_hilite; -GList *focus_order; -ObClient *focus_cycle_target; +ObClient *focus_client = NULL; +GList *focus_order = NULL; +ObClient *focus_cycle_target = NULL; struct { InternalWindow top; @@ -59,7 +59,7 @@ static void focus_cycle_destructor(ObClient *client, gpointer data) be used */ if (focus_cycle_target == client) - focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, CurrentTime); + focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); } static Window createWindow(Window parent, gulong mask, @@ -81,7 +81,7 @@ void focus_startup(gboolean reconfig) client_add_destructor(focus_cycle_destructor, NULL); /* start with nothing focused */ - focus_set_client(NULL); + focus_nothing(); focus_indicator.top.obwin.type = Window_Internal; focus_indicator.left.obwin.type = Window_Internal; @@ -156,48 +156,34 @@ static void push_to_top(ObClient *client) void focus_set_client(ObClient *client) { Window active; - ObClient *old; -#ifdef DEBUG_FOCUS - ob_debug("focus_set_client 0x%lx\n", client ? client->window : 0); -#endif + ob_debug_type(OB_DEBUG_FOCUS, + "focus_set_client 0x%lx\n", client ? client->window : 0); /* uninstall the old colormap, and install the new one */ screen_install_colormap(focus_client, FALSE); screen_install_colormap(client, TRUE); - if (client == NULL) { -#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_curtime); - XSync(ob_display, FALSE); - } - /* in the middle of cycling..? kill it. CurrentTime is fine, time won't be used. */ if (focus_cycle_target) - focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, CurrentTime); + focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); - old = focus_client; focus_client = client; - /* move to the top of the list */ - if (client != NULL) + if (client != NULL) { + /* move to the top of the list */ push_to_top(client); + /* remove hiliting from the window when it gets focused */ + client_hilite(client, FALSE); + } /* set the NET_ACTIVE_WINDOW hint, but preserve it on shutdown */ if (ob_state() != OB_STATE_EXITING) { active = client ? client->window : None; PROP_SET32(RootWindow(ob_display, ob_screen), net_active_window, window, active); - - /* remove hiliting from the window when it gets focused */ - if (client != NULL) - client_hilite(client, FALSE); } } @@ -207,14 +193,13 @@ ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old) ObClient *target = NULL; ObClient *desktop = NULL; - ob_debug("trying pointer stuff\n"); + 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) && - client_validate(target)) { - ob_debug("found in pointer stuff\n"); + if (client_normal(target) && client_can_focus(target)) { + ob_debug_type(OB_DEBUG_FOCUS, "found in pointer stuff\n"); return target; } } @@ -233,7 +218,12 @@ ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old) } #endif - ob_debug("trying the focus order\n"); + ob_debug_type(OB_DEBUG_FOCUS, "trying omnipresentness\n"); + if (allow_refocus && old && old->desktop == DESKTOP_ALL) + 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; @@ -242,16 +232,18 @@ ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old) focus off to nothing 2. it is validated. if the window is about to disappear, then don't try focus it. - 3. it is visible on the screen right now. - 4. it is a normal type window, don't fall back onto a dock or + 3. it is visible on the current desktop. this ignores + omnipresent windows, which are problematic in their own rite. + 4. it's not iconic + 5. 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) && client_validate(c) && - client_should_show(c)) + if (client_can_focus(c) && c->desktop == screen_desktop && + !c->iconic) { if (client_normal(c)) { - ob_debug("found in focus order\n"); + ob_debug_type(OB_DEBUG_FOCUS, "found in focus order\n"); return it->data; } else if (c->type == OB_CLIENT_TYPE_DESKTOP && !desktop) desktop = c; @@ -259,7 +251,7 @@ ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old) } /* as a last resort fallback to the desktop window if there is one. - (if there's more than one, then the one last focused.) + (if there's more than one, then the one most recently focused.) */ return desktop; } @@ -267,21 +259,33 @@ ObClient* focus_fallback_target(gboolean allow_refocus, ObClient *old) void focus_fallback(gboolean allow_refocus) { ObClient *new; - ObClient *old; - - /* save this before moving focus away to nothing */ - old = focus_client; + ObClient *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); + focus_nothing(); if ((new = focus_fallback_target(allow_refocus, old))) client_focus(new); } +void focus_nothing() +{ + /* Install our own colormap */ + if (focus_client != NULL) { + screen_install_colormap(focus_client, FALSE); + screen_install_colormap(NULL, TRUE); + } + + focus_client = NULL; + + /* when nothing will be focused, send focus to the backup target */ + XSetInputFocus(ob_display, screen_support_win, RevertToPointerRoot, + event_curtime); +} + static void popup_cycle(ObClient *c, gboolean show) { if (!show) { @@ -324,10 +328,15 @@ static void popup_cycle(ObClient *c, gboolean show) void focus_cycle_draw_indicator() { if (!focus_cycle_target) { + XEvent e; + XUnmapWindow(ob_display, focus_indicator.top.win); XUnmapWindow(ob_display, focus_indicator.left.win); XUnmapWindow(ob_display, focus_indicator.right.win); XUnmapWindow(ob_display, focus_indicator.bottom.win); + + /* kill enter events cause by this unmapping */ + event_ignore_queued_enters(); } else { /* if (focus_cycle_target) @@ -490,7 +499,7 @@ static gboolean valid_focus_target(ObClient *ft) } void focus_cycle(gboolean forward, gboolean linear, gboolean interactive, - gboolean dialog, gboolean done, gboolean cancel, Time time) + gboolean dialog, gboolean done, gboolean cancel) { static ObClient *first = NULL; static ObClient *t = NULL; @@ -551,7 +560,7 @@ void focus_cycle(gboolean forward, gboolean linear, gboolean interactive, done_cycle: if (done && focus_cycle_target) - client_activate(focus_cycle_target, FALSE, TRUE, time); + client_activate(focus_cycle_target, FALSE, TRUE); t = NULL; first = NULL; @@ -568,8 +577,7 @@ done_cycle: } void focus_directional_cycle(ObDirection dir, gboolean interactive, - gboolean dialog, gboolean done, gboolean cancel, - Time time) + gboolean dialog, gboolean done, gboolean cancel) { static ObClient *first = NULL; ObClient *ft = NULL; @@ -614,7 +622,7 @@ void focus_directional_cycle(ObDirection dir, gboolean interactive, done_cycle: if (done && focus_cycle_target) - client_activate(focus_cycle_target, FALSE, TRUE, time); + client_activate(focus_cycle_target, FALSE, TRUE); first = NULL; focus_cycle_target = NULL;