Client * clientGetTransient (Client * c) { g_return_val_if_fail (c != NULL, NULL); TRACE ("entering clientGetTransient"); if ((c->transient_for) && (c->transient_for != c->screen_info->xroot)) { return myScreenGetClientFromWindow (c->screen_info, c->transient_for, SEARCH_WINDOW); } return NULL; }
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)); }
static eventFilterStatus clientCycleEventFilter (XfwmEvent *event, gpointer data) { ScreenInfo *screen_info; DisplayInfo *display_info; ClientCycleData *passdata; Client *c, *removed; Client *c2 = NULL; eventFilterStatus status; KeyCode cancel, left, right, up, down; int key, modifiers; gboolean cycling; GList *li; TRACE ("entering"); passdata = (ClientCycleData *) data; c = tabwinGetSelected(passdata->tabwin); if (c == NULL) { return EVENT_FILTER_CONTINUE; } screen_info = c->screen_info; display_info = screen_info->display_info; cancel = screen_info->params->keys[KEY_CANCEL].keycode; left = screen_info->params->keys[KEY_LEFT].keycode; right = screen_info->params->keys[KEY_RIGHT].keycode; up = screen_info->params->keys[KEY_UP].keycode; down = screen_info->params->keys[KEY_DOWN].keycode; modifiers = (screen_info->params->keys[KEY_CYCLE_WINDOWS].modifier | screen_info->params->keys[KEY_CYCLE_REVERSE_WINDOWS].modifier); status = EVENT_FILTER_CONTINUE; removed = NULL; cycling = TRUE; /* Update the display time */ myDisplayUpdateCurrentTime (display_info, event); switch (event->meta.type) { case XFWM_EVENT_KEY: if (event->key.pressed) { key = myScreenGetKeyPressed (screen_info, &event->key); /* * We cannot simply check for key == KEY_CANCEL here because of the * modidier being pressed, so we need to look at the keycode directly. */ if (event->key.keycode == cancel) { c2 = tabwinSelectHead (passdata->tabwin); cycling = FALSE; } else if (event->key.keycode == up) { c2 = tabwinSelectDelta(passdata->tabwin, -1, 0); } else if (event->key.keycode == down) { c2 = tabwinSelectDelta(passdata->tabwin, 1, 0); } else if (event->key.keycode == left) { c2 = tabwinSelectDelta(passdata->tabwin, 0, -1); } else if (event->key.keycode == right) { c2 = tabwinSelectDelta(passdata->tabwin, -0, 1); } else if (key == KEY_CYCLE_REVERSE_WINDOWS) { TRACE ("cycle: previous"); c2 = tabwinSelectPrev(passdata->tabwin); } else if (key == KEY_CYCLE_WINDOWS) { TRACE ("cycle: next"); c2 = tabwinSelectNext(passdata->tabwin); } if (c2) { clientCycleUpdateWireframe (c2, passdata); } /* If last key press event had not our modifiers pressed, finish cycling */ if (!(event->key.state & modifiers)) { cycling = FALSE; } status = EVENT_FILTER_STOP; } else { int keysym = XkbKeycodeToKeysym (event->meta.xevent->xany.display, event->key.keycode, 0, 0); if (IsModifierKey(keysym)) { if (!(myScreenGetModifierPressed (screen_info) & modifiers)) { cycling = FALSE; } } } status = EVENT_FILTER_STOP; break; case XFWM_EVENT_BUTTON: if (event->button.pressed) { /* only accept events for the tab windows */ for (li = passdata->tabwin->tabwin_list; li != NULL; li = li->next) { if (GDK_WINDOW_XID (gtk_widget_get_window (li->data)) == event->meta.window) { if (event->button.button == Button1) { c2 = tabwinSelectHovered (passdata->tabwin); cycling = FALSE; break; } else if (event->button.button == Button4) { /* Mouse wheel scroll up */ TRACE ("cycle: previous"); c2 = tabwinSelectPrev(passdata->tabwin); } else if (event->button.button == Button5) { /* Mouse wheel scroll down */ TRACE ("cycle: next"); c2 = tabwinSelectNext(passdata->tabwin); } } if (c2) { clientCycleUpdateWireframe (c2, passdata); } } } status = EVENT_FILTER_STOP; break; case XFWM_EVENT_MOTION: break; case XFWM_EVENT_CROSSING: /* Track whether the pointer is inside one of the tab-windows */ for (li = passdata->tabwin->tabwin_list; li != NULL; li = li->next) { if (GDK_WINDOW_XID (gtk_widget_get_window (li->data)) == event->meta.window) { passdata->inside = event->crossing.enter; } } status = EVENT_FILTER_STOP; break; case XFWM_EVENT_XEVENT: switch (event->meta.xevent->type) { case DestroyNotify: status = EVENT_FILTER_CONTINUE; removed = myScreenGetClientFromWindow (screen_info, ((XDestroyWindowEvent *) event->meta.xevent)->window, SEARCH_WINDOW); if (removed == NULL) { break; /* No need to go any further */ } FALLTHROUGH; case UnmapNotify: status = EVENT_FILTER_CONTINUE; if (!removed) { removed = myScreenGetClientFromWindow (screen_info, ((XUnmapEvent *) event->meta.xevent)->window, SEARCH_WINDOW); if (removed == NULL) { break; /* No need to go any further */ } } c = tabwinRemoveClient(passdata->tabwin, removed); cycling = clientCycleUpdateWireframe (c, passdata); break; } break; } if (!cycling) { TRACE ("event loop now finished"); gtk_main_quit (); } return status; }
static eventFilterStatus clientCycleEventFilter (XEvent * xevent, gpointer data) { ScreenInfo *screen_info; DisplayInfo *display_info; ClientCycleData *passdata; Client *c, *removed; Client *c2 = NULL; eventFilterStatus status; KeyCode cancel, left, right, up, down; int key, modifiers; gboolean key_pressed, cycling, gone; GList *li; Window mouse_window = 0; XButtonEvent ev; TRACE ("entering clientCycleEventFilter"); passdata = (ClientCycleData *) data; c = tabwinGetSelected(passdata->tabwin); if (c == NULL) { return EVENT_FILTER_CONTINUE; } screen_info = c->screen_info; display_info = screen_info->display_info; cancel = screen_info->params->keys[KEY_CANCEL].keycode; left = screen_info->params->keys[KEY_LEFT].keycode; right = screen_info->params->keys[KEY_RIGHT].keycode; up = screen_info->params->keys[KEY_UP].keycode; down = screen_info->params->keys[KEY_DOWN].keycode; modifiers = (screen_info->params->keys[KEY_CYCLE_WINDOWS].modifier | screen_info->params->keys[KEY_CYCLE_REVERSE_WINDOWS].modifier); status = EVENT_FILTER_STOP; removed = NULL; cycling = TRUE; gone = FALSE; /* Update the display time */ myDisplayUpdateCurrentTime (display_info, xevent); switch (xevent->type) { case DestroyNotify: status = EVENT_FILTER_CONTINUE; if ((removed = myScreenGetClientFromWindow (screen_info, ((XDestroyWindowEvent *) xevent)->window, SEARCH_WINDOW)) == NULL) break; /* No need to go any further */ gone |= (c == removed); /* Walk through */ case UnmapNotify: status = EVENT_FILTER_CONTINUE; if (!removed && (removed = myScreenGetClientFromWindow (screen_info, ((XUnmapEvent *) xevent)->window, SEARCH_WINDOW)) == NULL) break; /* No need to go any further */ gone |= (c == removed); c = tabwinRemoveClient(passdata->tabwin, removed); /* Walk through */ case KeyPress: key_pressed = (xevent->type == KeyPress); if (gone || key_pressed) { if (key_pressed) { key = myScreenGetKeyPressed (screen_info, (XKeyEvent *) xevent); /* * We cannot simply check for key == KEY_CANCEL here because of the * modidier being pressed, so we need to look at the keycode directly. */ if (xevent->xkey.keycode == cancel) { c2 = tabwinSelectHead (passdata->tabwin); cycling = FALSE; } else if (xevent->xkey.keycode == up) { c2 = tabwinSelectDelta(passdata->tabwin, -1, 0); } else if (xevent->xkey.keycode == down) { c2 = tabwinSelectDelta(passdata->tabwin, 1, 0); } else if (xevent->xkey.keycode == left) { c2 = tabwinSelectDelta(passdata->tabwin, 0, -1); } else if (xevent->xkey.keycode == right) { c2 = tabwinSelectDelta(passdata->tabwin, -0, 1); } else if (key == KEY_CYCLE_REVERSE_WINDOWS) { TRACE ("Cycle: previous"); c2 = tabwinSelectPrev(passdata->tabwin); } else if (key == KEY_CYCLE_WINDOWS) { TRACE ("Cycle: next"); c2 = tabwinSelectNext(passdata->tabwin); } if (c2) { c = c2; } /* If last key press event had not our modifiers pressed, finish cycling */ if (!(xevent->xkey.state & modifiers)) { cycling = FALSE; } } } break; case KeyRelease: { int keysym = XLookupKeysym (&xevent->xkey, 0); if (IsModifierKey(keysym)) { if (!(myScreenGetModifierPressed (screen_info) & modifiers)) { cycling = FALSE; } } } break; case ButtonPress: status = EVENT_FILTER_STOP; ev = xevent->xbutton; /* window of the event, we might accept it later */ mouse_window = xevent->xbutton.window; if (mouse_window != 0) { /* only accept events for the tab windows */ for (li = passdata->tabwin->tabwin_list; li != NULL; li = li->next) { if (GDK_WINDOW_XID (gtk_widget_get_window (li->data)) == mouse_window) { if (ev.button == Button1) { cycling = FALSE; c = tabwinSelectHoveredWidget (passdata->tabwin); break; } else if (ev.button == Button4) { /* Mouse wheel scroll up */ TRACE ("Cycle: previous"); c2 = tabwinSelectPrev(passdata->tabwin); } else if (ev.button == Button5) { /* Mouse wheel scroll down */ TRACE ("Cycle: next"); c2 = tabwinSelectNext(passdata->tabwin); } } } if (c2) { c = c2; } } break; default: status = EVENT_FILTER_CONTINUE; break; } if (!cycling) { TRACE ("event loop now finished"); gtk_main_quit (); } if (status == EVENT_FILTER_STOP) { if (cycling) { if (c) { if (passdata->wireframe) { wireframeUpdate (c, passdata->wireframe); } } else { cycling = FALSE; } } } return status; }