gboolean clientTransientOrModalHasAncestor (Client * c, guint ws) { Client *c2; GList *list; ScreenInfo *screen_info; g_return_val_if_fail (c != NULL, FALSE); TRACE ("entering clientTransientOrModalHasAncestor"); if (!clientIsTransientOrModal (c)) { return FALSE; } screen_info = c->screen_info; for (list = screen_info->windows_stack; list; list = g_list_next (list)) { c2 = (Client *) list->data; if ((c2 != c) && !clientIsTransientOrModal (c2) && clientIsTransientOrModalFor (c, c2) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE) && (c2->win_workspace == ws) && (((ws == screen_info->current_ws) && FLAG_TEST (c2->xfwm_flags, XFWM_FLAG_VISIBLE)) || !FLAG_TEST (c2->flags, CLIENT_FLAG_ICONIFIED))) { return TRUE; } } return FALSE; }
gboolean clientIsValidTransientOrModal (Client * c) { g_return_val_if_fail (c != NULL, FALSE); TRACE ("entering clientIsValidTransientOrModal"); if (clientIsTransientOrModalForGroup (c)) { ScreenInfo *screen_info = c->screen_info; GList *list; /* Look for a valid transient or modal for the same group */ for (list = screen_info->windows_stack; list; list = g_list_next (list)) { Client *c2 = (Client *) list->data; if (c2 != c) { if (clientIsTransientOrModalFor (c, c2)) { /* We found one, look no further */ return TRUE; } } } } else if (clientIsTransientOrModal (c)) { return (clientGetTransient (c) != NULL); } return (FALSE); }
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); } } }