/* * Copyright (c) 2019 Derek Stevens, 2005 Russ Cox, 1994-1996 David Hogan * see README for license details */ #include #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "dat.h" #include "fns.h" #include "patchlevel.h" enum { GrabAltTab, GrabAltAny }; /*static int tabcode = 0x17; */ /*static int altcode = 0x40; */ /*static int pgupcode = 0x63; */ /*static int pgdowncode = 0x69; */ static void alttab(int shift); void keysetup(void) { int i; int tabcode = XKeysymToKeycode(dpy, XK_Tab); #ifdef DESTROY_KEY int dcode = XKeysymToKeycode(dpy, DESTROY_KEY); #endif #ifdef ICON_KEY int icode = XKeysymToKeycode(dpy, ICON_KEY); #endif #ifdef UNHIDE_KEY int ucode = XKeysymToKeycode(dpy, UNHIDE_KEY); #endif #ifdef MAX_KEY int mcode = XKeysymToKeycode(dpy, MAX_KEY); #endif #ifdef MOVE_KEY int vcode = XKeysymToKeycode(dpy, MOVE_KEY); #endif #ifdef RESIZE_KEY int rcode = XKeysymToKeycode(dpy, RESIZE_KEY); #endif #ifdef STICK_KEY int scode = XKeysymToKeycode(dpy, STICK_KEY); #endif #ifdef WRANGLE_KEY int acode = XKeysymToKeycode(dpy, WRANGLE_KEY); #endif #ifdef SNAPLEFT_KEY int hcode = XKeysymToKeycode(dpy, SNAPLEFT_KEY); #endif #ifdef SNAPRIGHT_KEY int lcode = XKeysymToKeycode(dpy, SNAPRIGHT_KEY); #endif #ifdef SNAPBOTTOM_KEY int jcode = XKeysymToKeycode(dpy, SNAPBOTTOM_KEY); #endif #ifdef SNAPTOP_KEY int kcode = XKeysymToKeycode(dpy, SNAPTOP_KEY); #endif #ifdef SNAPTOPLEFT_KEY int qcode = XKeysymToKeycode(dpy, SNAPTOPLEFT_KEY); #endif #ifdef SNAPBOTTOMLEFT_KEY int wcode = XKeysymToKeycode(dpy, SNAPBOTTOMLEFT_KEY); #endif #ifdef SNAPBOTTOMRIGHT_KEY int ocode = XKeysymToKeycode(dpy, SNAPBOTTOMRIGHT_KEY); #endif #ifdef SNAPTOPRIGHT_KEY int pcode = XKeysymToKeycode(dpy, SNAPTOPRIGHT_KEY); #endif #ifdef SNAPCENTER_KEY int ccode = XKeysymToKeycode(dpy, SNAPCENTER_KEY); #endif #ifdef LAUNCH_KEY int slcode = XKeysymToKeycode(dpy, LAUNCH_KEY); #endif #ifdef ZOOM_KEY int zcode = XKeysymToKeycode(dpy, ZOOM_KEY); #endif #ifdef NEXTVIRT_KEY int rightcode = XKeysymToKeycode(dpy, NEXTVIRT_KEY); #endif #ifdef PREVVIRT_KEY int leftcode = XKeysymToKeycode(dpy, PREVVIRT_KEY); #endif #ifdef DEVEL int tcode = XKeysymToKeycode(dpy, STICKYTOFRONT_KEY); int bcode = XKeysymToKeycode(dpy, STICKYTOBACK_KEY); #endif for (i = 0; i < num_screens; i++) { XGrabKey( dpy, tabcode, Mod1Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, tabcode, Mod1Mask | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #ifdef DESTROY_KEY XGrabKey( dpy, dcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, dcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef ICON_KEY XGrabKey( dpy, icode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, icode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef UNHIDE_KEY XGrabKey( dpy, ucode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, ucode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef RESIZE_KEY XGrabKey( dpy, rcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, rcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef MOVE_KEY XGrabKey( dpy, vcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, vcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef MAX_KEY XGrabKey( dpy, mcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, mcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef STICK_KEY XGrabKey( dpy, scode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, scode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef WRANGLE_KEY XGrabKey( dpy, acode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, acode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef SNAPLEFT_KEY XGrabKey( dpy, hcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, hcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef SNAPRIGHT_KEY XGrabKey( dpy, lcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, lcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef SNAPBOTTOM_KEY XGrabKey( dpy, jcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, jcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef SNAPTOP_KEY XGrabKey( dpy, kcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, kcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef SNAPTOPLEFT_KEY XGrabKey( dpy, qcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, qcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef SNAPBOTTOMLEFT_KEY XGrabKey( dpy, wcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, wcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef SNAPBOTTOMRIGHT_KEY XGrabKey( dpy, ocode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, ocode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef SNAPTOPRIGHT_KEY XGrabKey( dpy, pcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, pcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef SNAPCENTER_KEY XGrabKey( dpy, ccode, ShiftMask | SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, ccode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, ccode, ShiftMask | SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, ccode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef PREVVIRT_KEY XGrabKey( dpy, leftcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, leftcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef NEXTVIRT_KEY XGrabKey( dpy, rightcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, rightcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef LAUNCH_KEY XGrabKey( dpy, slcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, slcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif #ifdef ZOOM_KEY XGrabKey( dpy, zcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, zcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif XGrabKey( dpy, tabcode, Mod1Mask | ShiftMask, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, tabcode, Mod1Mask | ShiftMask | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #ifdef DEVEL XGrabKey( dpy, tcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, bcode, SHORTCUTMOD, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, tcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); XGrabKey( dpy, bcode, SHORTCUTMOD | Mod2Mask, screens[i].root, 0, GrabModeSync, GrabModeAsync); #endif /* XGrabKey(dpy, pgupcode, Mod1Mask, screens[i].root, 0, GrabModeSync, * GrabModeAsync); */ /* XGrabKey(dpy, pgdowncode, Mod1Mask, screens[i].root, 0, GrabModeSync, * GrabModeAsync); */ /* XGrabKey(dpy, altcode, 0, screens[i].root, 0, GrabModeSync, * GrabModeAsync); */ } } void keypress(XKeyEvent* e) { /* * process key press here */ static int m; static XRRMonitorInfo monitor; static int tabcode; #ifdef DESTROY_KEY static int dcode; #endif #ifdef ICON_KEY static int icode; #endif #ifdef UNHIDE_KEY static int ucode; #endif #ifdef MAX_KEY static int mcode; #endif #ifdef MOVE_KEY static int vcode; #endif #ifdef STICK_KEY static int scode; #endif #ifdef WRANGLE_KEY static int acode; #endif #ifdef RESIZE_KEY static int rcode; #endif #ifdef LAUNCH_KEY static int slcode; #endif #ifdef ZOOM_KEY static int zcode; #endif #ifdef SNAPLEFT_KEY static int hcode; #endif #ifdef SNAPRIGHT_KEY static int lcode; #endif #ifdef SNAPBOTTOM_KEY static int jcode; #endif #ifdef SNAPTOP_KEY int kcode; #endif #ifdef SNAPTOPLEFT_KEY static int qcode; #endif #ifdef SNAPBOTTOMLEFT_KEY static int wcode; #endif #ifdef SNAPBOTTOMRIGHT_KEY static int ocode; #endif #ifdef SNAPTOPRIGHT_KEY static int pcode; #endif #ifdef SNAPCENTER_KEY static int ccode; #endif #ifdef NEXTVIRT_KEY static int rightcode; #endif #ifdef PREVVIRT_KEY static int leftcode; #endif tabcode = XKeysymToKeycode(dpy, XK_Tab); #ifdef DESTROY_KEY dcode = XKeysymToKeycode(dpy, DESTROY_KEY); #endif #ifdef ICON_KEY icode = XKeysymToKeycode(dpy, ICON_KEY); #endif #ifdef UNHIDE_KEY ucode = XKeysymToKeycode(dpy, UNHIDE_KEY); #endif #ifdef MAX_KEY mcode = XKeysymToKeycode(dpy, MAX_KEY); #endif #ifdef MOVE_KEY vcode = XKeysymToKeycode(dpy, MOVE_KEY); #endif #ifdef STICK_KEY scode = XKeysymToKeycode(dpy, STICK_KEY); #endif #ifdef WRANGLE_KEY acode = XKeysymToKeycode(dpy, WRANGLE_KEY); #endif #ifdef RESIZE_KEY rcode = XKeysymToKeycode(dpy, RESIZE_KEY); #endif #ifdef LAUNCH_KEY slcode = XKeysymToKeycode(dpy, LAUNCH_KEY); #endif #ifdef ZOOM_KEY zcode = XKeysymToKeycode(dpy, ZOOM_KEY); #endif #ifdef SNAPLEFT_KEY hcode = XKeysymToKeycode(dpy, SNAPLEFT_KEY); #endif #ifdef SNAPRIGHT_KEY lcode = XKeysymToKeycode(dpy, SNAPRIGHT_KEY); #endif #ifdef SNAPBOTTOM_KEY jcode = XKeysymToKeycode(dpy, SNAPBOTTOM_KEY); #endif #ifdef SNAPTOP_KEY kcode = XKeysymToKeycode(dpy, SNAPTOP_KEY); #endif #ifdef SNAPTOPLEFT_KEY qcode = XKeysymToKeycode(dpy, SNAPTOPLEFT_KEY); #endif #ifdef SNAPBOTTOMLEFT_KEY wcode = XKeysymToKeycode(dpy, SNAPBOTTOMLEFT_KEY); #endif #ifdef SNAPBOTTOMRIGHT_KEY ocode = XKeysymToKeycode(dpy, SNAPBOTTOMRIGHT_KEY); #endif #ifdef SNAPTOPRIGHT_KEY pcode = XKeysymToKeycode(dpy, SNAPTOPRIGHT_KEY); #endif #ifdef SNAPCENTER_KEY ccode = XKeysymToKeycode(dpy, SNAPCENTER_KEY); #endif #ifdef NEXTVIRT_KEY rightcode = XKeysymToKeycode(dpy, NEXTVIRT_KEY); #endif #ifdef PREVVIRT_KEY leftcode = XKeysymToKeycode(dpy, PREVVIRT_KEY); #endif #ifdef DEVEL int tcode = XKeysymToKeycode(dpy, STICKYTOFRONT_KEY); int bcode = XKeysymToKeycode(dpy, STICKYTOBACK_KEY); #endif m = current ? getmonitorbyclient(current) : getmonitorbymouse(); monitor = monitorinfo[m]; /* basic wm functionality */ if (e->keycode == tabcode && (e->state & Mod1Mask) == (1 << 3)) alttab(e->state & ShiftMask); #ifdef DESTROY_KEY else if (e->keycode == dcode && (e->state & SHORTCUTMOD) == (MODBITS)) delete (current, 0); #endif #ifdef ICON_KEY else if (e->keycode == icode && (e->state & SHORTCUTMOD) == (MODBITS)) hide(current); #endif #ifdef UNHIDE_KEY else if (e->keycode == ucode && (e->state & SHORTCUTMOD) == (MODBITS)) unhide(0, 1); #endif #ifdef MOVE_KEY else if (e->keycode == vcode && (e->state & SHORTCUTMOD) == (MODBITS)) move(current, Button3); #endif #ifdef RESIZE_KEY else if (e->keycode == rcode && (e->state & SHORTCUTMOD) == (MODBITS)) reshape(current, Button3, sweep, 0); #endif #ifdef MAX_KEY else if (e->keycode == mcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, monitor.x, monitor.y, monitor.width, monitor.height, 1); #endif #ifdef STICK_KEY else if (e->keycode == scode && (e->state & SHORTCUTMOD) == (MODBITS)) stick(current); #endif /* move to another monitor */ #ifdef WRANGLE_KEY else if (e->keycode == acode && (e->state & SHORTCUTMOD) == (MODBITS)) { wrangle(current, m < nmonitors - 1 ? monitorinfo[++m] : monitorinfo[0]); } #endif /* toggle zoom mode */ #ifdef ZOOM_KEY else if (e->keycode == zcode && (e->state & SHORTCUTMOD) == (MODBITS)) { zoom = !zoom; if (zoom) { quickreshape( current, monitor.x, monitor.y, monitor.width, monitor.height, 1); } } #endif /* half snap */ #ifdef SNAPLEFT_KEY else if (e->keycode == hcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, monitor.x + GAPSZ, monitor.y + GAPSZ, monitor.width / 2 - 1.5 * GAPSZ, monitor.height - 2 * GAPSZ, 0); #endif #ifdef SNAPRIGHT_KEY else if (e->keycode == lcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, monitor.x + monitor.width / 2 + 0.5 * GAPSZ, monitor.y + GAPSZ, monitor.width / 2 - 1.5 * GAPSZ, monitor.height - 2 * GAPSZ, 0); #endif #ifdef SNAPBOTTOM_KEY else if (e->keycode == jcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, monitor.x + GAPSZ, monitor.y + monitor.height / 2 + 0.5 * GAPSZ, monitor.width - 2 * GAPSZ, monitor.height / 2 - 1.5 * GAPSZ, 0); #endif #ifdef SNAPTOP_KEY else if (e->keycode == kcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, monitor.x + GAPSZ, monitor.y + GAPSZ, monitor.width - 2 * GAPSZ, monitor.height / 2 - 1.5 * GAPSZ, 0); #endif /* quarter snap */ #ifdef SNAPTOPLEFT_KEY else if (e->keycode == qcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, monitor.x + GAPSZ, monitor.y + GAPSZ, monitor.width / 2 - 1.5 * GAPSZ, monitor.height / 2 - 1.5 * GAPSZ, 0); #endif #ifdef SNAPBOTTOMLEFT_KEY else if (e->keycode == wcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, monitor.x + GAPSZ, monitor.y + monitor.height / 2 + 0.5 * GAPSZ, monitor.width / 2 - 1.5 * GAPSZ, monitor.height / 2 - 1.5 * GAPSZ, 0); #endif #ifdef SNAPBOTTOMRIGHT_KEY else if (e->keycode == ocode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, monitor.x + monitor.width / 2 + 0.5 * GAPSZ, monitor.y + monitor.height / 2 + 0.5 * GAPSZ, monitor.width / 2 - 1.5 * GAPSZ, monitor.height / 2 - 1.5 * GAPSZ, 0); #endif #ifdef SNAPTOPRIGHT_KEY else if (e->keycode == pcode && (e->state & SHORTCUTMOD) == (MODBITS)) quickreshape( current, monitor.x + monitor.width / 2 + 0.5 * GAPSZ, monitor.y + GAPSZ, monitor.width / 2 - 1.5 * GAPSZ, monitor.height / 2 - 1.5 * GAPSZ, 0); #endif /* center snap */ #ifdef SNAPCENTER_KEY else if (e->keycode == ccode && (e->state & SHORTCUTMOD) == (MODBITS)) { if ((e->state & ShiftMask) == (1 << 0)) { #ifdef CENTERVMAX centerclient(current, monitor, 0); #else centerclient(current, monitor, 1); #endif } else { #ifdef CENTERVMAX centerclient(current, monitor, 1); #else centerclient(current, monitor, 0); #endif } } #endif #ifdef DEVEL /* manage autostuck windows */ if (e->keycode == tcode && (e->state & SHORTCUTMOD) == (MODBITS)) stickystack(1); if (e->keycode == bcode && (e->state & SHORTCUTMOD) == (MODBITS)) stickystack(0); #endif /* launch */ #ifdef LAUNCH_KEY else if (e->keycode == slcode && (e->state & SHORTCUTMOD) == (MODBITS)) { kbLaunch = 1; if (fork() == 0) { if (fork() == 0) { // this code doesn't seem necessary // close(ConnectionNumber(dpy)); // if (dpy != '\0') // putenv(dpy); signal(SIGINT, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGHUP, SIG_DFL); if (termprog != NULL) { execl(shell, shell, "-c", termprog, (char*)0); fprintf(stderr, "ryudo: exec %s", shell); perror(" failed"); } execlp("urxvt", "urxvt", (char*)0); execlp("9term", "9term", scrolling ? "-ws" : "-w", (char*)0); execlp("xterm", "xterm", "-ut", (char*)0); perror("ryudo: exec urxvt/9term/xterm failed"); exit(1); } exit(0); } wait((int*)0); } #endif /* switch virts */ #ifdef NEXTVIRT_KEY else if (e->keycode == rightcode && (e->state & SHORTCUTMOD) == (MODBITS)) { if (numvirtuals > 1) if (virt < numvirtuals - 1) switch_to(virt + 1); else switch_to(0); } #endif #ifdef PREVVIRT_KEY else if (e->keycode == leftcode && (e->state & SHORTCUTMOD) == (MODBITS)) { if (numvirtuals > 1) if (virt > 0) switch_to(virt - 1); else switch_to(numvirtuals - 1); } #endif XAllowEvents(dpy, SyncKeyboard, e->time); } void keyrelease(XKeyEvent* e) { XAllowEvents(dpy, SyncKeyboard, e->time); } void quickreshape(Client* c, int x, int y, int dx, int dy, int max) { if (c == 0) return; XMoveResizeWindow(dpy, c->parent, x, y, dx, dy); if (max) c->border = 0; else c->border = BORDER; c->x = x + c->border; c->y = y + c->border; c->dx = dx - 2 * c->border; c->dy = dy - 2 * c->border; XMoveResizeWindow(dpy, c->window, c->border, c->border, c->dx, c->dy); sendconfig(c); } void centerclient(Client* c, XRRMonitorInfo monitor, int vmax) { static int centeroffsetnum = CENTERNUM % 2 == 0 ? CENTERDEN - CENTERNUM : (CENTERDEN - CENTERNUM) / 2; static int centeroffsetden = CENTERNUM % 2 == 0 ? CENTERDEN * 2 : CENTERDEN; if (vmax) { quickreshape( c, monitor.x + centeroffsetnum * monitor.width / centeroffsetden, monitor.y + GAPSZ, CENTERNUM * monitor.width / CENTERDEN, monitor.height - 2 * GAPSZ, 0); } else { quickreshape( c, monitor.x + centeroffsetnum * monitor.width / centeroffsetden, monitor.y + centeroffsetnum * monitor.height / centeroffsetden, CENTERNUM * monitor.width / CENTERDEN, CENTERNUM * monitor.height / CENTERDEN, 0); } } static void alttab(int shift) { static int monitor; if (!shift) { shuffle(0); } else { monitor = getmonitorbyclient(current); if (monitor == nmonitors - 1) { monitor = 0; } else { monitor++; } shuffleonmonitor(monitor); } } #ifdef DEVEL void stickystack(int toTop) { Client* c; if (toTop) { for (c = clients; c->next; c = c->next) { if (c && isautostick(c)) top(c); } } else { for (c = clients; c->next; c = c->next) { if (c && !isautostick(c)) top(c); } } } #endif