keymodes.c (2842B)
1 /* function implementations */ 2 void 3 clearcmd(const Arg *arg) 4 { 5 unsigned int i; 6 7 for (i = 0; i < LENGTH(cmdkeysym); i++) { 8 cmdkeysym[i] = 0; 9 cmdmod[i] = 0; 10 } 11 } 12 13 void 14 grabkeys(void) 15 { 16 if (keymode == INSERTMODE) { 17 grabdefkeys(); 18 } else if (keymode == COMMANDMODE) { 19 XUngrabKey(dpy, AnyKey, AnyModifier, root); 20 XGrabKey(dpy, AnyKey, AnyModifier, root, 21 True, GrabModeAsync, GrabModeAsync); 22 } 23 } 24 25 int 26 isprotodel(Client *c) 27 { 28 int n; 29 Atom *protocols; 30 int ret = 0; 31 32 if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { 33 while (!ret && n--) 34 ret = protocols[n] == wmatom[WMDelete]; 35 XFree(protocols); 36 } 37 return ret; 38 } 39 40 41 void 42 keypress(XEvent *e) 43 { 44 unsigned int i, j; 45 Arg a = {0}; 46 Bool ismatch = False, maybematch = False; 47 KeySym keysym; 48 XKeyEvent *ev; 49 50 if (keymode == INSERTMODE) 51 keydefpress(e); 52 else if (keymode == COMMANDMODE) { 53 ev = &e->xkey; 54 keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); 55 if (keysym < XK_Shift_L || keysym > XK_Hyper_R) { 56 for (i = 0; i < LENGTH(cmdkeys); i++) 57 if (keysym == cmdkeys[i].keysym 58 && CLEANMASK(cmdkeys[i].mod) == CLEANMASK(ev->state) 59 && cmdkeys[i].func) { 60 cmdkeys[i].func(&(cmdkeys[i].arg)); 61 ismatch = True; 62 break; 63 } 64 if (!ismatch) { 65 for (j = 0; j < LENGTH(cmdkeysym); j++) 66 if (cmdkeysym[j] == 0) { 67 cmdkeysym[j] = keysym; 68 cmdmod[j] = ev->state; 69 break; 70 } 71 for (i = 0; i < LENGTH(commands); i++) { 72 for (j = 0; j < LENGTH(cmdkeysym); j++) { 73 if (cmdkeysym[j] == commands[i].keysym[j] 74 && CLEANMASK(cmdmod[j]) == CLEANMASK(commands[i].mod[j])) 75 ismatch = True; 76 else if (cmdkeysym[j] == 0 77 && cmdmod[j] == 0) { 78 ismatch = False; 79 maybematch = True; 80 break; 81 } else { 82 ismatch = False; 83 break; 84 } 85 } 86 if (ismatch) { 87 if (commands[i].func) 88 commands[i].func(&(commands[i].arg)); 89 clearcmd(&a); 90 break; 91 } 92 93 } 94 if (!maybematch) 95 clearcmd(&a); 96 } 97 } 98 } 99 } 100 101 void 102 onlyclient(const Arg *arg) 103 { 104 Client *c; 105 XEvent ev; 106 107 if (!selmon->sel) 108 return; 109 for (c = selmon->clients; c; c = c->next) { 110 if (c != selmon->sel && ISVISIBLE(c)) { 111 if (isprotodel(c)) { 112 ev.type = ClientMessage; 113 ev.xclient.window = c->win; 114 ev.xclient.message_type = wmatom[WMProtocols]; 115 ev.xclient.format = 32; 116 ev.xclient.data.l[0] = wmatom[WMDelete]; 117 ev.xclient.data.l[1] = CurrentTime; 118 XSendEvent(dpy, c->win, False, NoEventMask, &ev); 119 } 120 else { 121 XGrabServer(dpy); 122 XSetErrorHandler(xerrordummy); 123 XSetCloseDownMode(dpy, DestroyAll); 124 XKillClient(dpy, c->win); 125 XSync(dpy, False); 126 XSetErrorHandler(xerror); 127 XUngrabServer(dpy); 128 } 129 } 130 } 131 } 132 133 void 134 setkeymode(const Arg *arg) 135 { 136 Arg a = {0}; 137 138 if (!arg) 139 return; 140 keymode = arg->ui; 141 clearcmd(&a); 142 grabkeys(); 143 } 144