void clientFocusTop (ScreenInfo *screen_info, guint layer, guint32 timestamp) { ClientPair top_client; top_client = clientGetTopMostFocusable (screen_info, layer, NULL); if (top_client.prefered) { clientSetFocus (screen_info, top_client.prefered, timestamp, NO_FOCUS_FLAG); } else { clientSetFocus (screen_info, top_client.highest, timestamp, NO_FOCUS_FLAG); } }
static gboolean delayed_focus_cb (gpointer data) { ScreenInfo *screen_info; guint32 timestamp = (guint32) GPOINTER_TO_INT (data); g_return_val_if_fail (delayed_focus != NULL, FALSE); TRACE ("client \"%s\" (0x%lx)", delayed_focus->name, delayed_focus->window); screen_info = delayed_focus->screen_info; clientSetFocus (screen_info, delayed_focus, timestamp, NO_FOCUS_FLAG); focus_timeout = 0; delayed_focus = NULL; return (FALSE); }
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); } }
void clientPassFocus (ScreenInfo *screen_info, Client *c, GList *exclude_list) { DisplayInfo *display_info; ClientPair top_most; Client *new_focus; Client *current_focus; Window dr, window; unsigned int mask; int rx, ry, wx, wy; int look_in_layer; TRACE ("entering"); look_in_layer = (c ? c->win_layer : WIN_LAYER_NORMAL); new_focus = NULL; current_focus = client_focus; if (pending_focus) { current_focus = pending_focus; } if ((c || current_focus) && (c != current_focus)) { return; } display_info = screen_info->display_info; top_most = clientGetTopMostFocusable (screen_info, look_in_layer, exclude_list); if (!(screen_info->params->click_to_focus) && XQueryPointer (myScreenGetXDisplay (screen_info), screen_info->xroot, &dr, &window, &rx, &ry, &wx, &wy, &mask)) { new_focus = clientAtPosition (screen_info, rx, ry, exclude_list); } if (!new_focus) { new_focus = top_most.prefered ? top_most.prefered : top_most.highest; } clientSetFocus (screen_info, new_focus, myDisplayGetCurrentTime (display_info), FOCUS_IGNORE_MODAL | FOCUS_FORCE | FOCUS_TRANSITION); }
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); }
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); }
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 clientCycle (Client * c, XKeyEvent * ev) { ScreenInfo *screen_info; DisplayInfo *display_info; ClientCycleData passdata; GList *client_list, *selected; gboolean g1, g2; int key, modifier; Client *c2; g_return_if_fail (c != NULL); TRACE ("entering clientCycle"); screen_info = c->screen_info; display_info = screen_info->display_info; client_list = clientCycleCreateList (c); if (!client_list) { return; } modifier = 0; key = myScreenGetKeyPressed (screen_info, ev); if (key == KEY_CYCLE_REVERSE_WINDOWS) { selected = g_list_last (client_list); modifier = screen_info->params->keys[KEY_CYCLE_REVERSE_WINDOWS].modifier; } else { selected = g_list_next (client_list); modifier = screen_info->params->keys[KEY_CYCLE_WINDOWS].modifier; } if (!selected) { /* Only one element in list */ selected = client_list; } if (!modifier) { /* * The shortcut has no modifier so there's no point in entering * the cycle loop, just select the next or previous window and * that's it... */ clientCycleActivate ((Client *) selected->data); g_list_free (client_list); return; } g1 = myScreenGrabKeyboard (screen_info, ev->time); g2 = myScreenGrabPointer (screen_info, TRUE, LeaveWindowMask, None, ev->time); if (!g1 || !g2) { TRACE ("grab failed in clientCycle"); gdk_beep (); myScreenUngrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info)); myScreenUngrabPointer (screen_info, myDisplayGetCurrentTime (display_info)); g_list_free (client_list); return; } passdata.wireframe = None; TRACE ("entering cycle loop"); if (screen_info->params->cycle_draw_frame) { passdata.wireframe = wireframeCreate ((Client *) selected->data); } passdata.tabwin = tabwinCreate (&client_list, selected, screen_info->params->cycle_workspaces); eventFilterPush (display_info->xfilter, clientCycleEventFilter, &passdata); c2 = myScreenGetClientFromWindow (screen_info, GDK_WINDOW_XID (gtk_widget_get_window ( passdata.tabwin->tabwin_list->data)), SEARCH_FRAME); g_message ("%p", c2); clientSetFocus (screen_info, c2, ev->time, NO_FOCUS_FLAG); gtk_main (); eventFilterPop (display_info->xfilter); TRACE ("leaving cycle loop"); if (passdata.wireframe) { wireframeDelete (screen_info, passdata.wireframe); } updateXserverTime (display_info); c = tabwinGetSelected (passdata.tabwin); if (c) { clientCycleActivate (c); } tabwinDestroy (passdata.tabwin); g_free (passdata.tabwin); g_list_free (client_list); myScreenUngrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info)); myScreenUngrabPointer (screen_info, myDisplayGetCurrentTime (display_info)); }
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); } } }