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