all repos — openbox @ 12653a4153bccd5d9a46998753e7a1bc17479505

openbox fork - make it a bit more like ryudo

Redraw the focus cycle popup when the list of focusable windows changes, rather than closing it
Dana Jansens danakj@orodu.net
commit

12653a4153bccd5d9a46998753e7a1bc17479505

parent

d3a01a40f35cb3ae6c5ad8329291e86e2e599691

M openbox/client.copenbox/client.c

@@ -304,6 +304,7 @@ self = g_new0(ObClient, 1);

self->obwin.type = Window_Client; self->window = window; self->prompt = prompt; + self->managed = TRUE; /* non-zero defaults */ self->wmstate = WithdrawnState; /* make sure it gets updated first time */

@@ -632,6 +633,8 @@ if (!config_focus_under_mouse)

event_end_ignore_all_enters(ignore_start); mouse_grab_for_client(self, FALSE); + + self->managed = FALSE; /* remove the window from our save set, unless we are managing an internal ObPrompt window */
M openbox/client.hopenbox/client.h

@@ -73,6 +73,7 @@ struct _ObClient

{ ObWindow obwin; Window window; + gboolean managed; /*! If this client is managing an ObPrompt window, then this is set to the prompt */
M openbox/focus.copenbox/focus.c

@@ -98,6 +98,9 @@ active = client ? client->window : None;

PROP_SET32(RootWindow(ob_display, ob_screen), net_active_window, window, active); } + + /* make sure the focus cycle popup shows things in the right order */ + focus_cycle_reorder(); } static ObClient* focus_fallback_target(gboolean allow_refocus,

@@ -206,16 +209,14 @@ else

focus_order = g_list_insert(focus_order, c, 1); } - /* in the middle of cycling..? kill it. */ - focus_cycle_stop(c); + focus_cycle_add(c); } void focus_order_remove(ObClient *c) { focus_order = g_list_remove(focus_order, c); - /* in the middle of cycling..? kill it. */ - focus_cycle_stop(c); + focus_cycle_remove(c); } void focus_order_to_top(ObClient *c)

@@ -292,6 +293,9 @@ gboolean desktop_windows,

gboolean user_request) { gboolean ok = FALSE; + + /* see if the window is still managed or is going away */ + if (!ft->managed) return FALSE; /* it's on this desktop unless you want all desktops.
M openbox/focus_cycle.copenbox/focus_cycle.c

@@ -31,6 +31,7 @@ #include <X11/Xlib.h>

#include <glib.h> ObClient *focus_cycle_target = NULL; +static gboolean focus_cycle_directional = FALSE; static gboolean focus_cycle_iconic_windows; static gboolean focus_cycle_all_desktops; static gboolean focus_cycle_dock_windows;

@@ -51,26 +52,64 @@ {

if (reconfig) return; } -void focus_cycle_stop(ObClient *ifclient) +void focus_cycle_add(ObClient *ifclient) +{ + if (!(focus_cycle_target && ifclient && !focus_cycle_directional)) + return; + + if (focus_valid_target(ifclient, TRUE, + focus_cycle_iconic_windows, + focus_cycle_all_desktops, + focus_cycle_dock_windows, + focus_cycle_desktop_windows, + FALSE)) + focus_cycle_popup_refresh(focus_cycle_target, + focus_cycle_iconic_windows, + focus_cycle_all_desktops, + focus_cycle_dock_windows, + focus_cycle_desktop_windows); +} + +void focus_cycle_remove(ObClient *ifclient) { - /* stop focus cycling if the given client is a valid focus target, - and so the cycling is being disrupted */ - if (focus_cycle_target && ifclient && - /* shortcut check, it is what we are pointing at right now */ - (ifclient == focus_cycle_target || - /* it's shown but it shouldn't be anymore */ - focus_cycle_popup_is_showing(ifclient) || - /* it's not shown but it should be */ - focus_valid_target(ifclient, TRUE, - focus_cycle_iconic_windows, - focus_cycle_all_desktops, - focus_cycle_dock_windows, - focus_cycle_desktop_windows, - FALSE))) - { - focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE,TRUE); - focus_directional_cycle(0, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE); + if (!(focus_cycle_target && ifclient)) + return; + + if (focus_cycle_directional) { + if (focus_cycle_target == ifclient) { + focus_directional_cycle(0, TRUE, TRUE, TRUE, TRUE, + TRUE, TRUE, TRUE); + } } + else { + if (!focus_valid_target(ifclient, TRUE, + focus_cycle_iconic_windows, + focus_cycle_all_desktops, + focus_cycle_dock_windows, + focus_cycle_desktop_windows, + FALSE)) { + if (focus_cycle_target == ifclient) { + focus_cycle_target = + focus_cycle_popup_revert(focus_cycle_target); + focus_cycle_update_indicator(focus_cycle_target); + } + focus_cycle_popup_refresh(focus_cycle_target, + focus_cycle_iconic_windows, + focus_cycle_all_desktops, + focus_cycle_dock_windows, + focus_cycle_desktop_windows); + } + } +} + +void focus_cycle_reorder() +{ + if (focus_cycle_target && !focus_cycle_directional) + focus_cycle_popup_refresh(focus_cycle_target, + focus_cycle_iconic_windows, + focus_cycle_all_desktops, + focus_cycle_dock_windows, + focus_cycle_desktop_windows); } ObClient* focus_cycle(gboolean forward, gboolean all_desktops,

@@ -87,6 +126,7 @@

if (interactive) { if (cancel) { focus_cycle_target = NULL; + focus_cycle_directional = FALSE; goto done_cycle; } else if (done) goto done_cycle;

@@ -134,6 +174,7 @@ {

if (interactive) { if (ft != focus_cycle_target) { /* prevents flicker */ focus_cycle_target = ft; + focus_cycle_directional = FALSE; focus_cycle_draw_indicator(showbar ? ft : NULL); } if (dialog)

@@ -146,6 +187,7 @@ focus_cycle_desktop_windows);

return focus_cycle_target; } else if (ft != focus_cycle_target) { focus_cycle_target = ft; + focus_cycle_directional = FALSE; done = TRUE; break; }

@@ -156,6 +198,7 @@ done_cycle:

if (done && !cancel) ret = focus_cycle_target; focus_cycle_target = NULL; + focus_cycle_directional = FALSE; g_list_free(order); order = NULL;

@@ -275,6 +318,7 @@ ObClient *ret = NULL;

if (cancel) { focus_cycle_target = NULL; + focus_cycle_directional = FALSE; goto done_cycle; } else if (done && interactive) goto done_cycle;

@@ -310,6 +354,7 @@ }

if (ft && ft != focus_cycle_target) {/* prevents flicker */ focus_cycle_target = ft; + focus_cycle_directional = TRUE; if (!interactive) goto done_cycle; focus_cycle_draw_indicator(showbar ? ft : NULL);

@@ -328,6 +373,7 @@ if (done && !cancel) ret = focus_cycle_target;

first = NULL; focus_cycle_target = NULL; + focus_cycle_directional = FALSE; focus_cycle_draw_indicator(NULL); focus_cycle_popup_single_hide();
M openbox/focus_cycle.hopenbox/focus_cycle.h

@@ -47,6 +47,8 @@ gboolean showbar,

gboolean dialog, gboolean done, gboolean cancel); -void focus_cycle_stop(struct _ObClient *ifclient); +void focus_cycle_add(struct _ObClient *ifclient); +void focus_cycle_remove(struct _ObClient *ifclient); +void focus_cycle_reorder(); #endif
M openbox/focus_cycle_popup.copenbox/focus_cycle_popup.c

@@ -217,6 +217,22 @@ p->n_targets = n;

p->maxtextw = maxwidth; } +static void popup_cleanup(void) +{ + while(popup.targets) { + ObFocusCyclePopupTarget *t = popup.targets->data; + + RrImageUnref(t->icon); + g_free(t->text); + XDestroyWindow(ob_display, t->win); + g_free(t); + + popup.targets = g_list_delete_link(popup.targets, popup.targets); + } + popup.n_targets = 0; + popup.last_target = NULL; +} + static gchar *popup_get_name(ObClient *c) { ObClient *p;

@@ -479,18 +495,7 @@ event_end_ignore_all_enters(ignore_start);

popup.mapped = FALSE; - while(popup.targets) { - ObFocusCyclePopupTarget *t = popup.targets->data; - - RrImageUnref(t->icon); - g_free(t->text); - XDestroyWindow(ob_display, t->win); - g_free(t); - - popup.targets = g_list_delete_link(popup.targets, popup.targets); - } - popup.n_targets = 0; - popup.last_target = NULL; + popup_cleanup(); g_free(popup.hilite_rgba); popup.hilite_rgba = NULL;

@@ -536,7 +541,7 @@ {

icon_popup_hide(single_popup); } -gboolean focus_cycle_popup_is_showing(ObClient *client) +GList* focus_cycle_popup_is_showing(ObClient *client) { if (popup.mapped) { GList *it;

@@ -544,8 +549,46 @@

for (it = popup.targets; it; it = g_list_next(it)) { ObFocusCyclePopupTarget *t = it->data; if (t->client == client) - return TRUE; + return it; + } + } + return NULL; +} + +ObClient* focus_cycle_popup_revert(ObClient *target) +{ + GList *it; + + if (!popup.mapped) return NULL; + + for (it = popup.targets; it; it = g_list_next(it)) { + ObFocusCyclePopupTarget *t = it->data; + if (t->client == target) { + if (it->prev) + return ((ObFocusCyclePopupTarget*)it->prev->data)->client; + else if (it->next) + return ((ObFocusCyclePopupTarget*)it->next->data)->client; + else + return NULL; } } - return FALSE; + g_assert_not_reached(); +} + +void focus_cycle_popup_refresh(ObClient *target, + gboolean iconic_windows, + gboolean all_desktops, + gboolean dock_windows, + gboolean desktop_windows) +{ + if (!popup.mapped) return; + + popup_cleanup(); + popup_setup(&popup, TRUE, iconic_windows, all_desktops, + dock_windows, desktop_windows); + + popup.mapped = FALSE; + popup_render(&popup, target); + XFlush(ob_display); + popup.mapped = TRUE; }
M openbox/focus_cycle_popup.hopenbox/focus_cycle_popup.h

@@ -39,7 +39,13 @@ gboolean dock_windows,

gboolean desktop_windows); void focus_cycle_popup_single_hide(); -/*! Returns TRUE if the popup is showing the client, otherwise FALSE. */ -gboolean focus_cycle_popup_is_showing(struct _ObClient *client); +/*! Reverts from the current @target to a new focus cycle target window */ +struct _ObClient* focus_cycle_popup_revert(struct _ObClient *target); +/*! Redraws the focus cycle popup */ +void focus_cycle_popup_refresh(struct _ObClient *target, + gboolean iconic_windows, + gboolean all_desktops, + gboolean dock_windows, + gboolean desktop_windows); #endif
M openbox/screen.copenbox/screen.c

@@ -708,7 +708,8 @@ /* show windows from top to bottom */

for (it = stacking_list; it; it = g_list_next(it)) { if (WINDOW_IS_CLIENT(it->data)) { ObClient *c = it->data; - client_show(c); + if (client_show(c)) + focus_cycle_add(c); } }

@@ -719,8 +720,7 @@ for (it = g_list_last(stacking_list); it; it = g_list_previous(it)) {

if (WINDOW_IS_CLIENT(it->data)) { ObClient *c = it->data; if (client_hide(c)) { - /* in the middle of cycling..? kill it. */ - focus_cycle_stop(c); + focus_cycle_remove(c); if (c == focus_client) { /* c was focused and we didn't do fallback clearly so make