dwm/patch/keymodes.c
2021-06-14 08:54:23 +03:00

145 lines
2.8 KiB
C

/* 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();
}