void clientFocusDirection (Client * c, int dir) { Client *c2, *n = NULL; guint i; gint diff = 0, cur = 1024 * 1024; g_return_if_fail (c); TRACE ("entering focus direction"); for (c2 = c->next, i = 1; c && i < c->screen_info->client_count; i++, c2 = c2->next) { if (!clientSelectMask (c2, NULL, 0, WINDOW_REGULAR_FOCUSABLE)) { TRACE ("%s not in select mask", c2->name); continue; } switch (dir) { case FOCUS_UP: diff = c->y - c2->y; break; case FOCUS_DOWN: diff = c2->y - c->y; break; case FOCUS_LEFT: diff = c->x - c2->x; break; case FOCUS_RIGHT: diff = c2->x - c->x; break; } if (diff > 0 && cur > diff) { cur = diff; n = c2; } } if (n) { clientSetFocus (c->screen_info, n, myDisplayGetCurrentTime (c->screen_info->display_info), NO_FOCUS_FLAG); } }
static ClientPair clientGetTopMostFocusable (ScreenInfo *screen_info, guint layer, GList * exclude_list) { ClientPair top_client; Client *c; GList *list; TRACE ("entering"); top_client.prefered = top_client.highest = NULL; for (list = screen_info->windows_stack; list; list = g_list_next (list)) { c = (Client *) list->data; TRACE ("stack window \"%s\" (0x%lx), layer %i", c->name, c->window, (int) c->win_layer); if (!clientAcceptFocus (c) || (c->type & WINDOW_TYPE_DONT_FOCUS)) { continue; } if (!g_list_find (exclude_list, (gconstpointer) c)) { if (c->win_layer > layer) { break; } else if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE)) { if (clientSelectMask (c, NULL, 0, WINDOW_REGULAR_FOCUSABLE)) { top_client.prefered = c; } top_client.highest = c; } } } return top_client; }
Client * clientGetPrevious (Client * c, guint mask, guint type) { Client *c2; unsigned int i; TRACE ("entering"); if (c) { ScreenInfo *screen_info = c->screen_info; for (c2 = c->prev, i = 0; (c2) && (i < screen_info->client_count); c2 = c2->prev, i++) { if (clientSelectMask (c2, c, mask, type)) { return c2; } } } return NULL; }
static GList * clientCycleCreateList (Client *c) { ScreenInfo *screen_info; Client *c2; guint range, search_range, i; GList *client_list; g_return_val_if_fail (c, NULL); TRACE ("client \"%s\" (0x%lx)", c->name, c->window); screen_info = c->screen_info; range = clientGetCycleRange (screen_info); client_list = NULL; for (c2 = c, i = 0; c && i < screen_info->client_count; i++, c2 = c2->next) { search_range = range; /* * We want to include modals even if skip pager/taskbar because * modals are supposed to be focused */ if (clientIsModal(c2)) { search_range |= (SEARCH_INCLUDE_SKIP_TASKBAR | SEARCH_INCLUDE_SKIP_PAGER); } if (!clientSelectMask (c2, NULL, search_range, WINDOW_REGULAR_FOCUSABLE)) { TRACE ("%s not in select mask", c2->name); continue; } if (screen_info->params->cycle_apps_only) { /* * For apps only cycling, it's a tad more complicated * - We want "fake" dialogs, ie without a parent window * - We do not want dialogs but we want modals * - If a modal was added,we do not want to add * its parent again */ if (c2->type & WINDOW_TYPE_DIALOG) { if (clientIsValidTransientOrModal (c2)) { if (!clientIsModal(c2)) { TRACE ("%s is not modal", c2->name); continue; } } } else if (!(c2->type & WINDOW_NORMAL)) { { TRACE ("%s is not normal", c2->name); continue; } } else { if (g_list_find_custom (client_list, c2, clientCompareModal)) { TRACE ("%s found as modal list", c2->name); continue; } } } TRACE ("adding %s", c2->name); client_list = g_list_append (client_list, c2); } return client_list; }
void workspaceSwitch (ScreenInfo *screen_info, gint new_ws, Client * c2, gboolean update_focus, guint32 timestamp) { DisplayInfo *display_info; Client *c, *new_focus; Client *previous; GList *list; Window dr, window; gint rx, ry, wx, wy; unsigned int mask; g_return_if_fail (screen_info != NULL); TRACE ("entering workspaceSwitch"); display_info = screen_info->display_info; if ((new_ws == (gint) screen_info->current_ws) && (screen_info->params->toggle_workspaces)) { new_ws = (gint) screen_info->previous_ws; } if (new_ws == (gint) screen_info->current_ws) { return; } if (screen_info->params->wrap_cycle) { if (new_ws > (gint) screen_info->workspace_count - 1) { new_ws = 0; } if (new_ws < 0) { new_ws = (gint) screen_info->workspace_count - 1; } } else if ((new_ws > (gint) screen_info->workspace_count - 1) || (new_ws < 0)) { return; } screen_info->previous_ws = screen_info->current_ws; screen_info->current_ws = new_ws; new_focus = NULL; previous = NULL; c = clientGetFocus (); if (c2) { clientSetWorkspace (c2, new_ws, FALSE); } if (c) { if (c->type & WINDOW_REGULAR_FOCUSABLE) { previous = c; } if (c2 == c) { new_focus = c2; } } /* First pass: Show, from top to bottom */ for (list = g_list_last(screen_info->windows_stack); list; list = g_list_previous (list)) { c = (Client *) list->data; if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)) { clientSetWorkspace (c, new_ws, TRUE); } else if (new_ws == (gint) c->win_workspace) { if (!FLAG_TEST (c->flags, CLIENT_FLAG_ICONIFIED) && !FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE)) { if (!clientIsTransientOrModal (c) || !clientTransientOrModalHasAncestor (c, new_ws)) { clientShow (c, FALSE); } } } } /* Second pass: Hide from bottom to top */ for (list = screen_info->windows_stack; list; list = g_list_next (list)) { c = (Client *) list->data; if (new_ws != (gint) c->win_workspace) { if (c == previous) { FLAG_SET (previous->xfwm_flags, XFWM_FLAG_FOCUS); clientSetFocus (screen_info, NULL, timestamp, FOCUS_IGNORE_MODAL); } if (FLAG_TEST (c->xfwm_flags, XFWM_FLAG_VISIBLE) && !FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)) { if (!clientIsTransientOrModal (c) || !clientTransientOrModalHasAncestor (c, new_ws)) { clientWithdraw (c, new_ws, FALSE); } } } } /* Third pass: Check for focus, from top to bottom */ for (list = g_list_last(screen_info->windows_stack); list; list = g_list_previous (list)) { c = (Client *) list->data; if (FLAG_TEST (c->flags, CLIENT_FLAG_STICKY)) { if ((!new_focus) && (c == previous) && clientSelectMask (c, NULL, 0, WINDOW_REGULAR_FOCUSABLE)) { new_focus = c; } FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_FOCUS); } else if (new_ws == (gint) c->win_workspace) { if ((!new_focus) && FLAG_TEST (c->xfwm_flags, XFWM_FLAG_FOCUS)) { new_focus = c; } FLAG_UNSET (c->xfwm_flags, XFWM_FLAG_FOCUS); } } setNetCurrentDesktop (display_info, screen_info->xroot, new_ws); if (!(screen_info->params->click_to_focus)) { if (!(c2) && (XQueryPointer (myScreenGetXDisplay (screen_info), screen_info->xroot, &dr, &window, &rx, &ry, &wx, &wy, &mask))) { c = clientAtPosition (screen_info, rx, ry, NULL); if (c) { new_focus = c; } } } if (update_focus) { if (new_focus) { if ((screen_info->params->click_to_focus) && (screen_info->params->raise_on_click)) { if (!(screen_info->params->raise_on_focus) && !clientIsTopMost (new_focus)) { clientRaise (new_focus, None); } } clientSetFocus (screen_info, new_focus, timestamp, FOCUS_SORT); } else { clientFocusTop (screen_info, WIN_LAYER_FULLSCREEN, timestamp); } } }