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.

218 lines
3.5 KiB

18 years ago
18 years ago
18 years ago
18 years ago
  1. /*
  2. * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
  3. * See LICENSE file for license details.
  4. */
  5. #include "dwm.h"
  6. #include <regex.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <sys/types.h>
  10. #include <X11/Xutil.h>
  11. /* static */
  12. typedef struct {
  13. const char *pattern;
  14. char *tags[TLast];
  15. Bool isfloat;
  16. } Rule;
  17. /* CUSTOMIZE */
  18. static Rule rule[] = {
  19. /* class:instance tags isfloat */
  20. { "Firefox.*", { [Tnet] = "net" }, False },
  21. { "Gimp.*", { 0 }, True},
  22. };
  23. char *tags[TLast] = {
  24. [Tfnord] = "fnord",
  25. [Tdev] = "dev",
  26. [Tnet] = "net",
  27. [Twork] = "work",
  28. [Tmisc] = "misc",
  29. };
  30. void (*arrange)(Arg *) = dotile;
  31. /* END CUSTOMIZE */
  32. /* extern */
  33. void
  34. appendtag(Arg *arg)
  35. {
  36. if(!sel)
  37. return;
  38. sel->tags[arg->i] = tags[arg->i];
  39. arrange(NULL);
  40. }
  41. void
  42. dofloat(Arg *arg)
  43. {
  44. Client *c;
  45. for(c = clients; c; c = c->next) {
  46. c->ismax = False;
  47. if(c->tags[tsel]) {
  48. resize(c, True, TopLeft);
  49. }
  50. else
  51. ban(c);
  52. }
  53. if(sel && !sel->tags[tsel]) {
  54. if((sel = getnext(clients))) {
  55. higher(sel);
  56. focus(sel);
  57. }
  58. else
  59. XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
  60. }
  61. drawall();
  62. }
  63. void
  64. dotile(Arg *arg)
  65. {
  66. int n, i, w, h;
  67. Client *c;
  68. w = sw - mw;
  69. for(n = 0, c = clients; c; c = c->next)
  70. if(c->tags[tsel] && !c->isfloat)
  71. n++;
  72. if(n > 1)
  73. h = (sh - bh) / (n - 1);
  74. else
  75. h = sh - bh;
  76. for(i = 0, c = clients; c; c = c->next) {
  77. c->ismax = False;
  78. if(c->tags[tsel]) {
  79. if(c->isfloat) {
  80. higher(c);
  81. resize(c, True, TopLeft);
  82. continue;
  83. }
  84. if(n == 1) {
  85. c->x = sx;
  86. c->y = sy + bh;
  87. c->w = sw - 2 * c->border;
  88. c->h = sh - 2 * c->border - bh;
  89. }
  90. else if(i == 0) {
  91. c->x = sx;
  92. c->y = sy + bh;
  93. c->w = mw - 2 * c->border;
  94. c->h = sh - 2 * c->border - bh;
  95. }
  96. else if(h > bh) {
  97. c->x = sx + mw;
  98. c->y = sy + (i - 1) * h + bh;
  99. c->w = w - 2 * c->border;
  100. c->h = h - 2 * c->border;
  101. }
  102. else { /* fallback if h < bh */
  103. c->x = sx + mw;
  104. c->y = sy + bh;
  105. c->w = w - 2 * c->border;
  106. c->h = sh - 2 * c->border - bh;
  107. }
  108. resize(c, False, TopLeft);
  109. i++;
  110. }
  111. else
  112. ban(c);
  113. }
  114. if(!sel || (sel && !sel->tags[tsel])) {
  115. if((sel = getnext(clients))) {
  116. higher(sel);
  117. focus(sel);
  118. }
  119. else
  120. XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
  121. }
  122. drawall();
  123. }
  124. Client *
  125. getnext(Client *c)
  126. {
  127. for(; c && !c->tags[tsel]; c = c->next);
  128. return c;
  129. }
  130. Client *
  131. getprev(Client *c)
  132. {
  133. for(; c && !c->tags[tsel]; c = c->prev);
  134. return c;
  135. }
  136. void
  137. replacetag(Arg *arg)
  138. {
  139. int i;
  140. if(!sel)
  141. return;
  142. for(i = 0; i < TLast; i++)
  143. sel->tags[i] = NULL;
  144. appendtag(arg);
  145. }
  146. void
  147. settags(Client *c)
  148. {
  149. char classinst[256];
  150. static unsigned int len = sizeof(rule) / sizeof(rule[0]);
  151. unsigned int i, j;
  152. regex_t regex;
  153. regmatch_t tmp;
  154. Bool matched = False;
  155. XClassHint ch;
  156. if(XGetClassHint(dpy, c->win, &ch)) {
  157. snprintf(classinst, sizeof(classinst), "%s:%s",
  158. ch.res_class ? ch.res_class : "",
  159. ch.res_name ? ch.res_name : "");
  160. for(i = 0; !matched && i < len; i++) {
  161. if(!regcomp(&regex, rule[i].pattern, 0)) {
  162. if(!regexec(&regex, classinst, 1, &tmp, 0)) {
  163. for(j = 0; j < TLast; j++) {
  164. if(rule[i].tags[j])
  165. matched = True;
  166. c->tags[j] = rule[i].tags[j];
  167. }
  168. c->isfloat = rule[i].isfloat;
  169. }
  170. regfree(&regex);
  171. }
  172. }
  173. if(ch.res_class)
  174. XFree(ch.res_class);
  175. if(ch.res_name)
  176. XFree(ch.res_name);
  177. }
  178. if(!matched)
  179. c->tags[tsel] = tags[tsel];
  180. }
  181. void
  182. togglemode(Arg *arg)
  183. {
  184. arrange = arrange == dofloat ? dotile : dofloat;
  185. arrange(NULL);
  186. }
  187. void
  188. view(Arg *arg)
  189. {
  190. tsel = arg->i;
  191. arrange(NULL);
  192. drawall();
  193. }