static void clientCycleFocusAndRaise (Client *c) { ScreenInfo *screen_info; DisplayInfo *display_info; Client *sibling; g_return_if_fail (c != NULL); TRACE ("entering clientFocusAndRaise"); screen_info = c->screen_info; display_info = screen_info->display_info; sibling = clientGetTransientFor(c); clientRaise (sibling, None); clientShow (sibling, TRUE); clientUnshade (c); clientSetFocus (screen_info, c, myDisplayGetCurrentTime (display_info), NO_FOCUS_FLAG); clientSetLastRaise (c); }
static void clientCycleFocusAndRaise (Client *c) { ScreenInfo *screen_info; DisplayInfo *display_info; Client *ancestor; g_return_if_fail (c != NULL); TRACE ("client \"%s\" (0x%lx)", c->name, c->window); screen_info = c->screen_info; display_info = screen_info->display_info; ancestor = clientGetTransientFor(c); clientRaise (c, None); clientShow (ancestor, TRUE); clientUnshade (c); clientSetFocus (screen_info, c, myDisplayGetCurrentTime (display_info), NO_FOCUS_FLAG); clientSetLastRaise (c); }
gboolean clientFocusNew(Client * c) { ScreenInfo *screen_info; DisplayInfo *display_info; gboolean give_focus; gboolean prevent_focus_stealing; gboolean prevented; g_return_val_if_fail (c != NULL, FALSE); screen_info = c->screen_info; display_info = screen_info->display_info; give_focus = (c-> type & WINDOW_REGULAR_FOCUSABLE) && (screen_info->params->focus_new); prevent_focus_stealing = screen_info->params->prevent_focus_stealing; prevented = FALSE; /* Try to avoid focus stealing */ if (!clientAcceptFocus (c) || (c->type & WINDOW_TYPE_DONT_FOCUS)) { give_focus = FALSE; } else if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_USER_TIME) && (c->user_time == (guint32) 0)) { /* * _NET_WM_USER_TIME definition from http://standards.freedesktop.org/wm-spec * [...] "The special value of zero on a newly mapped window can be used to * request that the window not be initially focused when it is mapped." */ TRACE ("given startup time is nil, not focusing \"%s\"", c->name); give_focus = FALSE; prevented = FALSE; } else if ((client_focus) && (prevent_focus_stealing)) { if (client_focus->win_layer > c->win_layer) { TRACE ("not focusing \"%s\" because the current focused window is on a upper layer", c->name); give_focus = FALSE; prevented = TRUE; } else if (client_focus->win_layer < c->win_layer) { /* We don't use focus stealing prevention against upper layers */ TRACE ("ignoring startup prevention because the current focused window is on a lower layer"); give_focus = TRUE; prevented = FALSE; } else if (FLAG_TEST (client_focus->xfwm_flags, XFWM_FLAG_MOVING_RESIZING)) { give_focus = FALSE; prevented = TRUE; } else if (FLAG_TEST (c->flags, CLIENT_FLAG_HAS_STARTUP_TIME | CLIENT_FLAG_HAS_USER_TIME)) { TRACE ("current time is %u, time for \"%s\" is %u", (unsigned int) client_focus->user_time, c->name, (unsigned int) c->user_time); if (TIMESTAMP_IS_BEFORE (c->user_time, client_focus->user_time)) { give_focus = FALSE; prevented = TRUE; } } } if (FLAG_TEST(c->flags, CLIENT_FLAG_STATE_MODAL)) { give_focus = TRUE; } if (give_focus) { if (client_focus) { clientAdjustFullscreenLayer (client_focus, FALSE); } clientRaise (c, None); clientShow (c, TRUE); clientSetFocus (screen_info, c, myDisplayGetCurrentTime (display_info), FOCUS_IGNORE_MODAL); } else { Client *c2 = clientGetFocus(); clientSortRing(c); if ((c2 != NULL) && (c2->win_layer == c->win_layer) && prevented) { /* * Place windows under the currently focused only if focus * stealing prevention had prevented the focus transition, * otherwise, leave the unfocused window on top. */ clientLower (c, c2->frame); } else { clientRaise (c, None); } clientSortRing(c2); if (prevented) { TRACE ("setting WM_STATE_DEMANDS_ATTENTION flag on \"%s\" (0x%lx)", c->name, c->window); FLAG_SET (c->flags, CLIENT_FLAG_DEMANDS_ATTENTION); } clientShow (c, TRUE); clientSetNetState (c); } return (give_focus); }
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); } } }