#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;
if (reconfig) return;
}
-void focus_cycle_stop(ObClient *ifclient)
+void focus_cycle_add(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 && !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)
+{
+ 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,
if (interactive) {
if (cancel) {
focus_cycle_target = NULL;
+ focus_cycle_directional = FALSE;
goto done_cycle;
} else if (done)
goto done_cycle;
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)
return focus_cycle_target;
} else if (ft != focus_cycle_target) {
focus_cycle_target = ft;
+ focus_cycle_directional = FALSE;
done = TRUE;
break;
}
if (done && !cancel) ret = focus_cycle_target;
focus_cycle_target = NULL;
+ focus_cycle_directional = FALSE;
g_list_free(order);
order = NULL;
if (cancel) {
focus_cycle_target = NULL;
+ focus_cycle_directional = FALSE;
goto done_cycle;
} else if (done && interactive)
goto done_cycle;
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);
first = NULL;
focus_cycle_target = NULL;
+ focus_cycle_directional = FALSE;
focus_cycle_draw_indicator(NULL);
focus_cycle_popup_single_hide();
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;
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;
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;
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;
}