/* function implementations */ void clearcmd(const Arg *arg) { unsigned int i; for (i = 0; i < LENGTH(cmdkeysym); i++) { cmdkeysym[i] = 0; cmdmod[i] = 0; } } void grabkeys(void) { if (keymode == INSERTMODE) { grabdefkeys(); } else if (keymode == COMMANDMODE) { XUngrabKey(dpy, AnyKey, AnyModifier, root); XGrabKey(dpy, AnyKey, AnyModifier, root, True, GrabModeAsync, GrabModeAsync); } } int isprotodel(Client *c) { int n; Atom *protocols; int ret = 0; if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { while (!ret && n--) ret = protocols[n] == wmatom[WMDelete]; XFree(protocols); } return ret; } void keypress(XEvent *e) { unsigned int i, j; Arg a = {0}; Bool ismatch = False, maybematch = False; KeySym keysym; XKeyEvent *ev; if (keymode == INSERTMODE) keydefpress(e); else if (keymode == COMMANDMODE) { ev = &e->xkey; keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); if (keysym < XK_Shift_L || keysym > XK_Hyper_R) { for (i = 0; i < LENGTH(cmdkeys); i++) if (keysym == cmdkeys[i].keysym && CLEANMASK(cmdkeys[i].mod) == CLEANMASK(ev->state) && cmdkeys[i].func) { cmdkeys[i].func(&(cmdkeys[i].arg)); ismatch = True; break; } if (!ismatch) { for (j = 0; j < LENGTH(cmdkeysym); j++) if (cmdkeysym[j] == 0) { cmdkeysym[j] = keysym; cmdmod[j] = ev->state; break; } for (i = 0; i < LENGTH(commands); i++) { for (j = 0; j < LENGTH(cmdkeysym); j++) { if (cmdkeysym[j] == commands[i].keysym[j] && CLEANMASK(cmdmod[j]) == CLEANMASK(commands[i].mod[j])) ismatch = True; else if (cmdkeysym[j] == 0 && cmdmod[j] == 0) { ismatch = False; maybematch = True; break; } else { ismatch = False; break; } } if (ismatch) { if (commands[i].func) commands[i].func(&(commands[i].arg)); clearcmd(&a); break; } } if (!maybematch) clearcmd(&a); } } } } void onlyclient(const Arg *arg) { Client *c; XEvent ev; if (!selmon->sel) return; for (c = selmon->clients; c; c = c->next) { if (c != selmon->sel && ISVISIBLE(c)) { if (isprotodel(c)) { ev.type = ClientMessage; ev.xclient.window = c->win; ev.xclient.message_type = wmatom[WMProtocols]; ev.xclient.format = 32; ev.xclient.data.l[0] = wmatom[WMDelete]; ev.xclient.data.l[1] = CurrentTime; XSendEvent(dpy, c->win, False, NoEventMask, &ev); } else { XGrabServer(dpy); XSetErrorHandler(xerrordummy); XSetCloseDownMode(dpy, DestroyAll); XKillClient(dpy, c->win); XSync(dpy, False); XSetErrorHandler(xerror); XUngrabServer(dpy); } } } } void setkeymode(const Arg *arg) { Arg a = {0}; if (!arg) return; keymode = arg->ui; clearcmd(&a); grabkeys(); }