145 lines
2.8 KiB
C
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();
|
|
}
|
|
|