2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> |
2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> |
3 * See LICENSE file for license details. |
3 * See LICENSE file for license details. |
4 */ |
4 */ |
5 #include "dwm.h" |
5 #include "dwm.h" |
6 |
6 |
|
7 #include <regex.h> |
|
8 #include <stdio.h> |
7 #include <string.h> |
9 #include <string.h> |
|
10 #include <sys/types.h> |
8 #include <X11/Xutil.h> |
11 #include <X11/Xutil.h> |
9 |
12 |
10 /* static */ |
13 /* static */ |
|
14 |
|
15 typedef struct { |
|
16 const char *pattern; |
|
17 char *tags[TLast]; |
|
18 Bool isfloat; |
|
19 } Rule; |
11 |
20 |
12 /* CUSTOMIZE */ |
21 /* CUSTOMIZE */ |
13 static Rule rule[] = { |
22 static Rule rule[] = { |
14 /* class instance tags isfloat */ |
23 /* class instance tags isfloat */ |
15 { "Firefox-bin", "firefox-bin", { [Twww] = "www" }, False }, |
24 { "Firefox.*", { [Twww] = "www" }, False }, |
|
25 { "Gimp.*", { 0 }, True}, |
16 }; |
26 }; |
17 |
27 |
18 /* extern */ |
28 /* extern */ |
19 |
29 |
20 /* CUSTOMIZE */ |
30 /* CUSTOMIZE */ |
162 } |
172 } |
163 |
173 |
164 void |
174 void |
165 settags(Client *c) |
175 settags(Client *c) |
166 { |
176 { |
167 XClassHint ch; |
177 char classinst[256]; |
168 static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0; |
178 static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0; |
169 unsigned int i, j; |
179 unsigned int i, j; |
|
180 regex_t regex; |
|
181 regmatch_t tmp; |
170 Bool matched = False; |
182 Bool matched = False; |
|
183 XClassHint ch; |
171 |
184 |
172 if(!len) { |
185 if(!len) { |
173 c->tags[tsel] = tags[tsel]; |
186 c->tags[tsel] = tags[tsel]; |
174 return; |
187 return; |
175 } |
188 } |
176 |
189 |
177 if(XGetClassHint(dpy, c->win, &ch)) { |
190 if(XGetClassHint(dpy, c->win, &ch)) { |
178 if(ch.res_class && ch.res_name) { |
191 snprintf(classinst, sizeof(classinst), "%s:%s", |
179 for(i = 0; i < len; i++) |
192 ch.res_class ? ch.res_class : "", |
180 if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class)) |
193 ch.res_name ? ch.res_name : ""); |
181 && !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance))) |
194 for(i = 0; !matched && i < len; i++) { |
182 { |
195 if(!regcomp(®ex, rule[i].pattern, 0)) { |
183 for(j = 0; j < TLast; j++) |
196 if(!regexec(®ex, classinst, 1, &tmp, 0)) { |
|
197 for(j = 0; j < TLast; j++) { |
|
198 if(rule[i].tags[j]) |
|
199 matched = True; |
184 c->tags[j] = rule[i].tags[j]; |
200 c->tags[j] = rule[i].tags[j]; |
|
201 } |
185 c->isfloat = rule[i].isfloat; |
202 c->isfloat = rule[i].isfloat; |
186 matched = True; |
|
187 break; |
|
188 } |
203 } |
|
204 regfree(®ex); |
|
205 } |
189 } |
206 } |
190 if(ch.res_class) |
207 if(ch.res_class) |
191 XFree(ch.res_class); |
208 XFree(ch.res_class); |
192 if(ch.res_name) |
209 if(ch.res_name) |
193 XFree(ch.res_name); |
210 XFree(ch.res_name); |
194 } |
211 } |
195 |
|
196 if(!matched) |
212 if(!matched) |
197 c->tags[tsel] = tags[tsel]; |
213 c->tags[tsel] = tags[tsel]; |
198 } |
214 } |
199 |
215 |
200 void |
216 void |