You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
2.8 KiB
144 lines
2.8 KiB
/* 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(); |
|
} |
|
|
|
|