Another copy of my dotfiles. Because I don't completely trust GitHub.
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.

142 lines
2.8 KiB

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