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.

206 lines
3.2 KiB

19 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 <string.h>
  7. #include <X11/Xutil.h>
  8. /* static */
  9. /* CUSTOMIZE */
  10. static Rule rule[] = {
  11. /* class instance tags isfloat */
  12. { "Firefox-bin", "firefox-bin", { [Twww] = "www" }, False },
  13. };
  14. /* extern */
  15. /* CUSTOMIZE */
  16. char *tags[TLast] = {
  17. [Tscratch] = "scratch",
  18. [Tdev] = "dev",
  19. [Twww] = "www",
  20. [Twork] = "work",
  21. };
  22. void (*arrange)(Arg *) = dotile;
  23. void
  24. appendtag(Arg *arg)
  25. {
  26. if(!sel)
  27. return;
  28. sel->tags[arg->i] = tags[arg->i];
  29. arrange(NULL);
  30. }
  31. void
  32. dofloat(Arg *arg)
  33. {
  34. Client *c;
  35. arrange = dofloat;
  36. for(c = clients; c; c = c->next) {
  37. setgeom(c);
  38. if(c->tags[tsel]) {
  39. resize(c, True, TopLeft);
  40. }
  41. else
  42. ban(c);
  43. }
  44. if(sel && !sel->tags[tsel]) {
  45. if((sel = getnext(clients, tsel))) {
  46. higher(sel);
  47. focus(sel);
  48. }
  49. }
  50. drawall();
  51. }
  52. void
  53. dotile(Arg *arg)
  54. {
  55. Client *c;
  56. int n, i, w, h;
  57. w = sw - mw;
  58. arrange = dotile;
  59. for(n = 0, c = clients; c; c = c->next)
  60. if(c->tags[tsel] && !c->isfloat)
  61. n++;
  62. if(n > 1)
  63. h = (sh - bh) / (n - 1);
  64. else
  65. h = sh - bh;
  66. for(i = 0, c = clients; c; c = c->next) {
  67. setgeom(c);
  68. if(c->tags[tsel]) {
  69. if(c->isfloat) {
  70. higher(c);
  71. resize(c, True, TopLeft);
  72. continue;
  73. }
  74. if(n == 1) {
  75. *c->x = sx;
  76. *c->y = sy + bh;
  77. *c->w = sw - 2 * c->border;
  78. *c->h = sh - 2 * c->border - bh;
  79. }
  80. else if(i == 0) {
  81. *c->x = sx;
  82. *c->y = sy + bh;
  83. *c->w = mw - 2 * c->border;
  84. *c->h = sh - 2 * c->border - bh;
  85. }
  86. else if(h > bh) {
  87. *c->x = sx + mw;
  88. *c->y = sy + (i - 1) * h + bh;
  89. *c->w = w - 2 * c->border;
  90. *c->h = h - 2 * c->border;
  91. }
  92. else { /* fallback if h < bh */
  93. *c->x = sx + mw;
  94. *c->y = sy + bh;
  95. *c->w = w - 2 * c->border;
  96. *c->h = sh - 2 * c->border - bh;
  97. }
  98. resize(c, False, TopLeft);
  99. i++;
  100. }
  101. else
  102. ban(c);
  103. }
  104. if(!sel || (sel && !sel->tags[tsel])) {
  105. if((sel = getnext(clients, tsel))) {
  106. higher(sel);
  107. focus(sel);
  108. }
  109. }
  110. drawall();
  111. }
  112. Client *
  113. getnext(Client *c, unsigned int t)
  114. {
  115. for(; c && !c->tags[t]; c = c->next);
  116. return c;
  117. }
  118. void
  119. heretag(Arg *arg)
  120. {
  121. int i;
  122. Client *c;
  123. if(arg->i == tsel)
  124. return;
  125. if(!(c = getnext(clients, arg->i)))
  126. return;
  127. for(i = 0; i < TLast; i++)
  128. c->tags[i] = NULL;
  129. c->tags[tsel] = tags[tsel];
  130. pop(c);
  131. focus(c);
  132. }
  133. void
  134. replacetag(Arg *arg)
  135. {
  136. int i;
  137. if(!sel)
  138. return;
  139. for(i = 0; i < TLast; i++)
  140. sel->tags[i] = NULL;
  141. appendtag(arg);
  142. }
  143. void
  144. settags(Client *c)
  145. {
  146. XClassHint ch;
  147. static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0;
  148. unsigned int i, j;
  149. Bool matched = False;
  150. if(!len) {
  151. c->tags[tsel] = tags[tsel];
  152. return;
  153. }
  154. if(XGetClassHint(dpy, c->win, &ch)) {
  155. if(ch.res_class && ch.res_name) {
  156. for(i = 0; i < len; i++)
  157. if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class))
  158. && !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance)))
  159. {
  160. for(j = 0; j < TLast; j++)
  161. c->tags[j] = rule[i].tags[j];
  162. c->isfloat = rule[i].isfloat;
  163. matched = True;
  164. break;
  165. }
  166. }
  167. if(ch.res_class)
  168. XFree(ch.res_class);
  169. if(ch.res_name)
  170. XFree(ch.res_name);
  171. }
  172. if(!matched)
  173. c->tags[tsel] = tags[tsel];
  174. }
  175. void
  176. view(Arg *arg)
  177. {
  178. tsel = arg->i;
  179. arrange(NULL);
  180. drawall();
  181. }