tag.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /* See LICENSE file for copyright and license details. */
  2. #include "dwm.h"
  3. #include <regex.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <X11/Xatom.h>
  8. #include <X11/Xutil.h>
  9. /* static */
  10. typedef struct {
  11. const char *prop;
  12. const char *tags;
  13. Bool isfloating;
  14. } Rule;
  15. typedef struct {
  16. regex_t *propregex;
  17. regex_t *tagregex;
  18. } Regs;
  19. TAGS
  20. RULES
  21. static Regs *regs = NULL;
  22. static unsigned int nrules = 0;
  23. static char prop[512];
  24. static unsigned int
  25. idxoftag(const char *tag) {
  26. unsigned int i;
  27. for(i = 0; i < ntags; i++)
  28. if(tags[i] == tag)
  29. return i;
  30. return 0;
  31. }
  32. /* extern */
  33. void
  34. applyrules(Client *c) {
  35. unsigned int i, j;
  36. regmatch_t tmp;
  37. Bool matched = False;
  38. XClassHint ch = { 0 };
  39. /* rule matching */
  40. XGetClassHint(dpy, c->win, &ch);
  41. snprintf(prop, sizeof prop, "%s:%s:%s",
  42. ch.res_class ? ch.res_class : "",
  43. ch.res_name ? ch.res_name : "", c->name);
  44. for(i = 0; i < nrules; i++)
  45. if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) {
  46. c->isfloating = rules[i].isfloating;
  47. for(j = 0; regs[i].tagregex && j < ntags; j++) {
  48. if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
  49. matched = True;
  50. c->tags[j] = True;
  51. }
  52. }
  53. }
  54. if(ch.res_class)
  55. XFree(ch.res_class);
  56. if(ch.res_name)
  57. XFree(ch.res_name);
  58. if(!matched)
  59. for(i = 0; i < ntags; i++)
  60. c->tags[i] = seltags[i];
  61. }
  62. void
  63. compileregs(void) {
  64. unsigned int i;
  65. regex_t *reg;
  66. if(regs)
  67. return;
  68. nrules = sizeof rules / sizeof rules[0];
  69. regs = emallocz(nrules * sizeof(Regs));
  70. for(i = 0; i < nrules; i++) {
  71. if(rules[i].prop) {
  72. reg = emallocz(sizeof(regex_t));
  73. if(regcomp(reg, rules[i].prop, REG_EXTENDED))
  74. free(reg);
  75. else
  76. regs[i].propregex = reg;
  77. }
  78. if(rules[i].tags) {
  79. reg = emallocz(sizeof(regex_t));
  80. if(regcomp(reg, rules[i].tags, REG_EXTENDED))
  81. free(reg);
  82. else
  83. regs[i].tagregex = reg;
  84. }
  85. }
  86. }
  87. Bool
  88. isvisible(Client *c) {
  89. unsigned int i;
  90. for(i = 0; i < ntags; i++)
  91. if(c->tags[i] && seltags[i])
  92. return True;
  93. return False;
  94. }
  95. void
  96. tag(const char *arg) {
  97. unsigned int i;
  98. if(!sel)
  99. return;
  100. for(i = 0; i < ntags; i++)
  101. sel->tags[i] = arg == NULL;
  102. i = idxoftag(arg);
  103. if(i >= 0 && i < ntags)
  104. sel->tags[i] = True;
  105. saveconfig(sel);
  106. arrange();
  107. }
  108. void
  109. togglefloating(const char *arg) {
  110. if(!sel || isfloating())
  111. return;
  112. sel->isfloating = !sel->isfloating;
  113. if(sel->isfloating) {
  114. resize(sel, sel->x, sel->y, sel->w, sel->h, True);
  115. saveconfig(sel);
  116. }
  117. arrange();
  118. }
  119. void
  120. toggletag(const char *arg) {
  121. unsigned int i, j;
  122. if(!sel)
  123. return;
  124. i = idxoftag(arg);
  125. sel->tags[i] = !sel->tags[i];
  126. for(j = 0; j < ntags && !sel->tags[j]; j++);
  127. if(j == ntags)
  128. sel->tags[i] = True;
  129. saveconfig(sel);
  130. arrange();
  131. }
  132. void
  133. toggleview(const char *arg) {
  134. unsigned int i, j;
  135. i = idxoftag(arg);
  136. seltags[i] = !seltags[i];
  137. for(j = 0; j < ntags && !seltags[j]; j++);
  138. if(j == ntags)
  139. seltags[i] = True; /* cannot toggle last view */
  140. arrange();
  141. }
  142. void
  143. view(const char *arg) {
  144. unsigned int i;
  145. for(i = 0; i < ntags; i++)
  146. seltags[i] = arg == NULL;
  147. i = idxoftag(arg);
  148. if(i >= 0 && i < ntags)
  149. seltags[i] = True;
  150. arrange();
  151. }