key.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
  3. * See LICENSE file for license details.
  4. */
  5. #include <fcntl.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <unistd.h>
  10. #include <X11/keysym.h>
  11. #include <X11/Xatom.h>
  12. #include "dwm.h"
  13. static void ckill(Arg *arg);
  14. static void nextc(Arg *arg);
  15. static void prevc(Arg *arg);
  16. static void max(Arg *arg);
  17. static void ttrunc(Arg *arg);
  18. static void tappend(Arg *arg);
  19. static void zoom(Arg *arg);
  20. /********** CUSTOMIZE **********/
  21. const char *term[] = {
  22. "urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-fn",
  23. "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*",NULL
  24. };
  25. const char *browse[] = { "firefox", NULL };
  26. const char *xlock[] = { "xlock", NULL };
  27. Key key[] = {
  28. /* modifier key function arguments */
  29. { Mod1Mask, XK_Return, zoom, { 0 } },
  30. { Mod1Mask, XK_k, prevc, { 0 } },
  31. { Mod1Mask, XK_j, nextc, { 0 } },
  32. { Mod1Mask, XK_m, max, { 0 } },
  33. { Mod1Mask, XK_0, view, { .i = Tscratch } },
  34. { Mod1Mask, XK_1, view, { .i = Tdev } },
  35. { Mod1Mask, XK_2, view, { .i = Twww } },
  36. { Mod1Mask, XK_3, view, { .i = Twork } },
  37. { Mod1Mask, XK_space, tiling, { 0 } },
  38. { Mod1Mask|ShiftMask, XK_space, floating, { 0 } },
  39. { Mod1Mask|ShiftMask, XK_0, ttrunc, { .i = Tscratch } },
  40. { Mod1Mask|ShiftMask, XK_1, ttrunc, { .i = Tdev } },
  41. { Mod1Mask|ShiftMask, XK_2, ttrunc, { .i = Twww } },
  42. { Mod1Mask|ShiftMask, XK_3, ttrunc, { .i = Twork } },
  43. { Mod1Mask|ShiftMask, XK_c, ckill, { 0 } },
  44. { Mod1Mask|ShiftMask, XK_q, quit, { 0 } },
  45. { Mod1Mask|ShiftMask, XK_Return, spawn, { .argv = term } },
  46. { Mod1Mask|ShiftMask, XK_w, spawn, { .argv = browse } },
  47. { Mod1Mask|ShiftMask, XK_l, spawn, { .argv = xlock } },
  48. { ControlMask, XK_0, tappend, { .i = Tscratch } },
  49. { ControlMask, XK_1, tappend, { .i = Tdev } },
  50. { ControlMask, XK_2, tappend, { .i = Twww } },
  51. { ControlMask, XK_3, tappend, { .i = Twork } },
  52. };
  53. /********** CUSTOMIZE **********/
  54. void
  55. grabkeys()
  56. {
  57. static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
  58. unsigned int i;
  59. KeyCode code;
  60. for(i = 0; i < len; i++) {
  61. code = XKeysymToKeycode(dpy, key[i].keysym);
  62. XUngrabKey(dpy, code, key[i].mod, root);
  63. XGrabKey(dpy, code, key[i].mod, root, True,
  64. GrabModeAsync, GrabModeAsync);
  65. }
  66. }
  67. void
  68. keypress(XEvent *e)
  69. {
  70. XKeyEvent *ev = &e->xkey;
  71. static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
  72. unsigned int i;
  73. KeySym keysym;
  74. keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
  75. for(i = 0; i < len; i++)
  76. if((keysym == key[i].keysym) && (key[i].mod == ev->state)) {
  77. if(key[i].func)
  78. key[i].func(&key[i].arg);
  79. return;
  80. }
  81. }
  82. static void
  83. zoom(Arg *arg)
  84. {
  85. Client **l, *c;
  86. if(!sel)
  87. return;
  88. if(sel == next(clients) && sel->next) {
  89. if((c = next(sel->next)))
  90. sel = c;
  91. }
  92. for(l = &clients; *l && *l != sel; l = &(*l)->next);
  93. *l = sel->next;
  94. sel->next = clients; /* pop */
  95. clients = sel;
  96. arrange(NULL);
  97. focus(sel);
  98. }
  99. static void
  100. max(Arg *arg)
  101. {
  102. if(!sel)
  103. return;
  104. sel->x = sx;
  105. sel->y = sy + bh;
  106. sel->w = sw - 2 * sel->border;
  107. sel->h = sh - 2 * sel->border - bh;
  108. craise(sel);
  109. resize(sel, False);
  110. }
  111. static void
  112. tappend(Arg *arg)
  113. {
  114. if(!sel)
  115. return;
  116. sel->tags[arg->i] = tags[arg->i];
  117. arrange(NULL);
  118. }
  119. static void
  120. ttrunc(Arg *arg)
  121. {
  122. int i;
  123. if(!sel)
  124. return;
  125. for(i = 0; i < TLast; i++)
  126. sel->tags[i] = NULL;
  127. tappend(arg);
  128. }
  129. static void
  130. prevc(Arg *arg)
  131. {
  132. Client *c;
  133. if(!sel)
  134. return;
  135. if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
  136. craise(c);
  137. focus(c);
  138. }
  139. }
  140. static void
  141. nextc(Arg *arg)
  142. {
  143. Client *c;
  144. if(!sel)
  145. return;
  146. if(!(c = next(sel->next)))
  147. c = next(clients);
  148. if(c) {
  149. craise(c);
  150. c->revert = sel;
  151. focus(c);
  152. }
  153. }
  154. static void
  155. ckill(Arg *arg)
  156. {
  157. if(!sel)
  158. return;
  159. if(sel->proto & WM_PROTOCOL_DELWIN)
  160. send_message(sel->win, wm_atom[WMProtocols], wm_atom[WMDelete]);
  161. else
  162. XKillClient(dpy, sel->win);
  163. }