void clientCycle (Client * c, XfwmEventKey *event) { ScreenInfo *screen_info; DisplayInfo *display_info; ClientCycleData passdata; GList *client_list, *selected; int key, modifier; 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; client_list = clientCycleCreateList (c); if (!client_list) { return; } modifier = 0; key = myScreenGetKeyPressed (screen_info, event); 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; } myScreenGrabPointer (screen_info, TRUE, EnterWindowMask | LeaveWindowMask, None, event->time); /* Grabbing the pointer may fail e.g. if the user is doing a drag'n drop */ if (!myScreenGrabKeyboard (screen_info, KeyPressMask | KeyReleaseMask, event->time)) { TRACE ("grab failed in clientCycle"); myDisplayBeep (display_info); myScreenUngrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info)); myScreenUngrabPointer (screen_info, myDisplayGetCurrentTime (display_info)); g_list_free (client_list); return; } passdata.wireframe = NULL; passdata.inside = FALSE; TRACE ("entering cycle loop"); if (screen_info->params->cycle_raise) { clientRaise ((Client *) selected->data, None); } 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); gtk_main (); eventFilterPop (display_info->xfilter); TRACE ("leaving cycle loop"); if (passdata.wireframe) { wireframeDelete (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); if (passdata.inside) { /* A bit of a hack, flush EnterNotify if the pointer is inside * the tabwin to defeat focus-follow-mouse tracking */ eventFilterPush (display_info->xfilter, clientCycleFlushEventFilter, display_info); gtk_main (); eventFilterPop (display_info->xfilter); } myScreenUngrabKeyboard (screen_info, myDisplayGetCurrentTime (display_info)); myScreenUngrabPointer (screen_info, myDisplayGetCurrentTime (display_info)); }
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)); }