static gboolean clientCycleUpdateWireframe (Client *c, ClientCycleData *passdata) { if (c) { if (c->screen_info->params->cycle_raise) { clientRaise (c, None); } if (passdata->wireframe) { wireframeUpdate (c, passdata->wireframe); } return TRUE; } return FALSE; }
WireFrame * wireframeCreate (Client *c) { ScreenInfo *screen_info; WireFrame *wireframe; XSetWindowAttributes attrs; XVisualInfo xvisual_info; Visual *xvisual; int depth; g_return_val_if_fail (c != NULL, None); TRACE ("client \"%s\" (0x%lx)", c->name, c->window); screen_info = c->screen_info; wireframe = g_new0 (WireFrame, 1); wireframe->screen_info = screen_info; wireframe->mapped = FALSE; wireframe->width = 0; wireframe->height = 0; wireframe->cr = NULL; wireframe->surface = NULL; wireframe->alpha = (compositorIsActive (screen_info) ? 0.5 : 1.0); if (compositorIsActive (screen_info) && XMatchVisualInfo (myScreenGetXDisplay (screen_info), screen_info->screen, 32, TrueColor, &xvisual_info)) { xvisual = xvisual_info.visual; depth = xvisual_info.depth; wireframe->xcolormap = XCreateColormap (myScreenGetXDisplay (screen_info), screen_info->xroot, xvisual, AllocNone); } else { xvisual = screen_info->visual; depth = screen_info->depth; wireframe->xcolormap = screen_info->cmap; } attrs.override_redirect = True; attrs.colormap = wireframe->xcolormap; attrs.background_pixel = BlackPixel (myScreenGetXDisplay (screen_info), screen_info->screen); attrs.border_pixel = BlackPixel (myScreenGetXDisplay (screen_info), screen_info->screen); wireframe->xwindow = XCreateWindow (myScreenGetXDisplay (screen_info), screen_info->xroot, frameExtentX (c), frameExtentY (c), frameExtentWidth (c), frameExtentHeight (c), 0, depth, InputOutput, xvisual, CWOverrideRedirect | CWColormap | CWBackPixel | CWBorderPixel, &attrs); if (compositorIsActive (screen_info)) { /* Cairo */ wireframeInitColor (wireframe); wireframe->surface = cairo_xlib_surface_create (myScreenGetXDisplay (screen_info), wireframe->xwindow, xvisual, frameExtentWidth (c), frameExtentHeight (c)); wireframe->cr = cairo_create (wireframe->surface); cairo_set_line_width (wireframe->cr, OUTLINE_WIDTH_CAIRO); cairo_set_line_join (wireframe->cr, CAIRO_LINE_JOIN_MITER); } wireframeUpdate (c, wireframe); return (wireframe); }
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; }