#include <glib.h>
ObClient *focus_cycle_target = NULL;
+static gboolean focus_cycle_iconic_windows;
static gboolean focus_cycle_all_desktops;
static gboolean focus_cycle_dock_windows;
static gboolean focus_cycle_desktop_windows;
if (reconfig) return;
}
-void focus_cycle_stop()
+void focus_cycle_stop(ObClient *ifclient)
{
- if (focus_cycle_target) {
+ /* stop focus cycling if the given client is a valid focus target,
+ and so the cycling is being disrupted */
+ if (focus_cycle_target && ifclient &&
+ focus_cycle_target_valid(ifclient,
+ focus_cycle_iconic_windows,
+ focus_cycle_all_desktops,
+ focus_cycle_dock_windows,
+ focus_cycle_desktop_windows))
+ {
focus_cycle(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
focus_directional_cycle(0, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE);
}
ft->modal ||
!ft->skip_taskbar);
- /* it's not going to just send fous off somewhere else (modal window) */
- ok = ok && ft == client_focus_target(ft);
+ /* it's not going to just send focus off somewhere else (modal window),
+ unless that modal window is not one of our valid targets, then let
+ you choose this window and bring the modal one here */
+ {
+ ObClient *cft = client_focus_target(ft);
+ ok = ok && (ft == cft || !focus_cycle_target_valid(cft,
+ iconic_windows,
+ all_desktops,
+ dock_windows,
+ desktop_windows));
+ }
return ok;
}
gboolean linear, gboolean interactive,
gboolean dialog, gboolean done, gboolean cancel)
{
- static ObClient *first = NULL;
static ObClient *t = NULL;
static GList *order = NULL;
GList *it, *start, *list;
if (!focus_order)
goto done_cycle;
- if (!first) first = focus_client;
-
if (linear) list = client_list;
else list = focus_order;
} else {
if (focus_cycle_target == NULL) {
- focus_cycle_all_desktops = FALSE;
+ focus_cycle_iconic_windows = TRUE;
+ focus_cycle_all_desktops = all_desktops;
focus_cycle_dock_windows = dock_windows;
focus_cycle_desktop_windows = desktop_windows;
- focus_cycle_target = focus_client;
- }
+ start = it = g_list_find(list, focus_client);
+ } else
+ start = it = g_list_find(list, focus_cycle_target);
- start = it = g_list_find(list, focus_cycle_target);
if (!start) /* switched desktops or something? */
start = it = forward ? g_list_last(list) : g_list_first(list);
if (!start) goto done_cycle;
if (it == NULL) it = g_list_last(list);
}
ft = it->data;
- if (focus_cycle_target_valid(ft, TRUE,
+ if (focus_cycle_target_valid(ft,
+ focus_cycle_iconic_windows,
focus_cycle_all_desktops,
focus_cycle_dock_windows,
focus_cycle_desktop_windows))
}
if (dialog)
/* same arguments as focus_target_valid */
- focus_cycle_popup_show(ft, TRUE,
+ focus_cycle_popup_show(ft,
+ focus_cycle_iconic_windows,
focus_cycle_all_desktops,
focus_cycle_dock_windows,
focus_cycle_desktop_windows);
client_activate(focus_cycle_target, FALSE, TRUE);
t = NULL;
- first = NULL;
focus_cycle_target = NULL;
g_list_free(order);
order = NULL;
ObClient *best_client, *cur;
GList *it;
- if(!client_list)
+ if (!client_list)
return NULL;
/* first, find the centre coords of the currently focused window */
my_cy = c->frame->area.y + c->frame->area.height / 2;
best_score = -1;
- best_client = NULL;
+ best_client = c;
- for(it = g_list_first(client_list); it; it = g_list_next(it)) {
+ for (it = g_list_first(client_list); it; it = g_list_next(it)) {
cur = it->data;
/* the currently selected window isn't interesting */
- if(cur == c)
+ if (cur == c)
continue;
if (!focus_cycle_target_valid(it->data, FALSE, FALSE, dock_windows,
desktop_windows))
his_cy = (cur->frame->area.y - my_cy)
+ cur->frame->area.height / 2;
- if(dir == OB_DIRECTION_NORTHEAST || dir == OB_DIRECTION_SOUTHEAST ||
- dir == OB_DIRECTION_SOUTHWEST || dir == OB_DIRECTION_NORTHWEST) {
+ if (dir == OB_DIRECTION_NORTHEAST || dir == OB_DIRECTION_SOUTHEAST ||
+ dir == OB_DIRECTION_SOUTHWEST || dir == OB_DIRECTION_NORTHWEST)
+ {
gint tx;
/* Rotate the diagonals 45 degrees counterclockwise.
* To do this, multiply the matrix /+h +h\ with the
his_cx = tx;
}
- switch(dir) {
+ switch (dir) {
case OB_DIRECTION_NORTH:
case OB_DIRECTION_SOUTH:
case OB_DIRECTION_NORTHEAST:
}
/* the target must be in the requested direction */
- if(distance <= 0)
+ if (distance <= 0)
continue;
/* Calculate score for this window. The smaller the better. */
/* windows more than 45 degrees off the direction are
* heavily penalized and will only be chosen if nothing
* else within a million pixels */
- if(offset > distance)
+ if (offset > distance)
score += 1000000;
- if(best_score == -1 || score < best_score)
- best_client = cur,
- best_score = score;
+ if (best_score == -1 || score < best_score) {
+ best_client = cur;
+ best_score = score;
+ }
}
return best_client;
goto done_cycle;
if (focus_cycle_target == NULL) {
+ focus_cycle_iconic_windows = FALSE;
focus_cycle_all_desktops = FALSE;
focus_cycle_dock_windows = dock_windows;
focus_cycle_desktop_windows = desktop_windows;
- focus_cycle_target = focus_client;
}
if (!first) first = focus_client;
if (focus_cycle_target)
ft = focus_find_directional(focus_cycle_target, dir, dock_windows,
desktop_windows);
+ else if (first)
+ ft = focus_find_directional(first, dir, dock_windows, desktop_windows);
else {
GList *it;
for (it = focus_order; it; it = g_list_next(it))
- if (focus_cycle_target_valid(it->data, FALSE, FALSE,
+ if (focus_cycle_target_valid(it->data,
+ focus_cycle_iconic_windows,
+ focus_cycle_all_desktops,
focus_cycle_dock_windows,
focus_cycle_desktop_windows))
ft = it->data;
if (focus_cycle_target && dialog) {
/* same arguments as focus_target_valid */
focus_cycle_popup_single_show(focus_cycle_target,
- FALSE, FALSE,
+ focus_cycle_iconic_windows,
+ focus_cycle_all_desktops,
focus_cycle_dock_windows,
focus_cycle_desktop_windows);
return;