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.

144 lines
2.3 KiB

  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 <stdlib.h>
  9. #include <string.h>
  10. #include <sys/types.h>
  11. #include <X11/Xutil.h>
  12. typedef struct {
  13. const char *clpattern;
  14. const char *tpattern;
  15. Bool isfloat;
  16. } Rule;
  17. typedef struct {
  18. regex_t *clregex;
  19. regex_t *tregex;
  20. } RReg;
  21. /* static */
  22. TAGS
  23. RULES
  24. static RReg *rreg = NULL;
  25. static unsigned int len = 0;
  26. /* extern */
  27. Client *
  28. getnext(Client *c)
  29. {
  30. for(; c && !isvisible(c); c = c->next);
  31. return c;
  32. }
  33. Client *
  34. getprev(Client *c)
  35. {
  36. for(; c && !isvisible(c); c = c->prev);
  37. return c;
  38. }
  39. void
  40. initrregs()
  41. {
  42. unsigned int i;
  43. regex_t *reg;
  44. if(rreg)
  45. return;
  46. len = sizeof(rule) / sizeof(rule[0]);
  47. rreg = emallocz(len * sizeof(RReg));
  48. for(i = 0; i < len; i++) {
  49. if(rule[i].clpattern) {
  50. reg = emallocz(sizeof(regex_t));
  51. if(regcomp(reg, rule[i].clpattern, 0))
  52. free(reg);
  53. else
  54. rreg[i].clregex = reg;
  55. }
  56. if(rule[i].tpattern) {
  57. reg = emallocz(sizeof(regex_t));
  58. if(regcomp(reg, rule[i].tpattern, 0))
  59. free(reg);
  60. else
  61. rreg[i].tregex = reg;
  62. }
  63. }
  64. }
  65. void
  66. settags(Client *c)
  67. {
  68. char prop[512];
  69. unsigned int i, j;
  70. regmatch_t tmp;
  71. Bool matched = False;
  72. XClassHint ch;
  73. if(XGetClassHint(dpy, c->win, &ch)) {
  74. snprintf(prop, sizeof(prop), "%s:%s:%s",
  75. ch.res_class ? ch.res_class : "",
  76. ch.res_name ? ch.res_name : "", c->name);
  77. for(i = 0; !matched && i < len; i++)
  78. if(rreg[i].clregex && !regexec(rreg[i].clregex, prop, 1, &tmp, 0)) {
  79. c->isfloat = rule[i].isfloat;
  80. for(j = 0; rreg[i].tregex && j < ntags; j++) {
  81. if(!regexec(rreg[i].tregex, tags[j], 1, &tmp, 0)) {
  82. matched = True;
  83. c->tags[j] = True;
  84. }
  85. }
  86. }
  87. if(ch.res_class)
  88. XFree(ch.res_class);
  89. if(ch.res_name)
  90. XFree(ch.res_name);
  91. }
  92. if(!matched)
  93. for(i = 0; i < ntags; i++)
  94. c->tags[i] = seltag[i];
  95. }
  96. void
  97. tag(Arg *arg)
  98. {
  99. unsigned int i;
  100. if(!sel)
  101. return;
  102. for(i = 0; i < ntags; i++)
  103. sel->tags[i] = False;
  104. sel->tags[arg->i] = True;
  105. settitle(sel);
  106. if(!isvisible(sel))
  107. arrange(NULL);
  108. else
  109. drawstatus();
  110. }
  111. void
  112. toggletag(Arg *arg)
  113. {
  114. unsigned int i;
  115. if(!sel)
  116. return;
  117. sel->tags[arg->i] = !sel->tags[arg->i];
  118. for(i = 0; i < ntags && !sel->tags[i]; i++);
  119. if(i == ntags)
  120. sel->tags[arg->i] = True;
  121. settitle(sel);
  122. if(!isvisible(sel))
  123. arrange(NULL);
  124. }