Xinqi Bao's Git

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