summaryrefslogtreecommitdiff
path: root/patch/keymodes.c
diff options
context:
space:
mode:
Diffstat (limited to 'patch/keymodes.c')
-rw-r--r--patch/keymodes.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/patch/keymodes.c b/patch/keymodes.c
new file mode 100644
index 0000000..6f2f840
--- /dev/null
+++ b/patch/keymodes.c
@@ -0,0 +1,144 @@
+/* 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();
+}
+