JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
added heretag command which allows to tag a client of a foreign tag with current tag
[dwm.git] / tag.c
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
7 #include <string.h>
8 #include <X11/Xutil.h>
9
10 /* static */
11
12 /* CUSTOMIZE */ 
13 static Rule rule[] = {
14         /* class                        instance        tags                                            isfloat */
15         { "Firefox-bin",        "Gecko",        { [Twww] = "www" },                     False },
16 };
17
18 /* extern */
19
20 /* CUSTOMIZE */
21 char *tags[TLast] = {
22         [Tscratch] = "scratch",
23         [Tdev] = "dev",
24         [Twww] = "www",
25         [Twork] = "work",
26 };
27 void (*arrange)(Arg *) = dotile;
28
29 void
30 appendtag(Arg *arg)
31 {
32         if(!sel)
33                 return;
34
35         sel->tags[arg->i] = tags[arg->i];
36         arrange(NULL);
37 }
38
39 void
40 dofloat(Arg *arg)
41 {
42         Client *c;
43
44         arrange = dofloat;
45         for(c = clients; c; c = c->next) {
46                 if(c->tags[tsel])
47                         resize(c, True);
48                 else
49                         ban(c);
50         }
51         if(sel && !sel->tags[tsel]) {
52                 if((sel = getnext(clients, tsel))) {
53                         higher(sel);
54                         focus(sel);
55                 }
56         }
57         drawall();
58 }
59
60 void
61 dotile(Arg *arg)
62 {
63         Client *c;
64         int n, i, w, h;
65
66         w = sw - mw;
67         arrange = dotile;
68         for(n = 0, c = clients; c; c = c->next)
69                 if(c->tags[tsel] && !c->isfloat)
70                         n++;
71
72         if(n > 1)
73                 h = (sh - bh) / (n - 1);
74         else
75                 h = sh - bh;
76
77         for(i = 0, c = clients; c; c = c->next) {
78                 if(c->tags[tsel]) {
79                         if(c->isfloat) {
80                                 higher(c);
81                                 resize(c, True);
82                                 continue;
83                         }
84                         if(n == 1) {
85                                 c->x = sx;
86                                 c->y = sy + bh;
87                                 c->w = sw - 2 * c->border;
88                                 c->h = sh - 2 * c->border - bh;
89                         }
90                         else if(i == 0) {
91                                 c->x = sx;
92                                 c->y = sy + bh;
93                                 c->w = mw - 2 * c->border;
94                                 c->h = sh - 2 * c->border - bh;
95                         }
96                         else {
97                                 c->x = sx + mw;
98                                 c->y = sy + (i - 1) * h + bh;
99                                 c->w = w - 2 * c->border;
100                                 c->h = h - 2 * c->border;
101                         }
102                         resize(c, False);
103                         i++;
104                 }
105                 else
106                         ban(c);
107         }
108         if(!sel || (sel && !sel->tags[tsel])) {
109                 if((sel = getnext(clients, tsel))) {
110                         higher(sel);
111                         focus(sel);
112                 }
113         }
114         drawall();
115 }
116
117 Client *
118 getnext(Client *c, unsigned int t)
119 {
120         for(; c && !c->tags[t]; c = c->next);
121         return c;
122 }
123
124 void
125 heretag(Arg *arg)
126 {
127         int i;
128         Client *c;
129
130         if(arg->i == tsel)
131                 return;
132
133         if(!(c = getnext(clients, arg->i)))
134                 return;
135
136         for(i = 0; i < TLast; i++)
137                 c->tags[i] = NULL;
138         c->tags[tsel] = tags[tsel];
139         arrange(NULL);
140         focus(c);
141 }
142
143 void
144 replacetag(Arg *arg)
145 {
146         int i;
147         if(!sel)
148                 return;
149
150         for(i = 0; i < TLast; i++)
151                 sel->tags[i] = NULL;
152         appendtag(arg);
153 }
154
155 void
156 settags(Client *c)
157 {
158         XClassHint ch;
159         static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0;
160         unsigned int i, j;
161         Bool matched = False;
162
163         if(!len) {
164                 c->tags[tsel] = tags[tsel];
165                 return;
166         }
167
168         if(XGetClassHint(dpy, c->win, &ch)) {
169                 if(ch.res_class && ch.res_name) {
170                         for(i = 0; i < len; i++)
171                                 if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class))
172                                         && !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance)))
173                                 {
174                                         for(j = 0; j < TLast; j++)
175                                                 c->tags[j] = rule[i].tags[j];
176                                         c->isfloat = rule[i].isfloat;
177                                         matched = True;
178                                         break;
179                                 }
180                 }
181                 if(ch.res_class)
182                         XFree(ch.res_class);
183                 if(ch.res_name)
184                         XFree(ch.res_name);
185         }
186
187         if(!matched)
188                 c->tags[tsel] = tags[tsel];
189 }
190
191 void
192 view(Arg *arg)
193 {
194         tsel = arg->i;
195         arrange(NULL);
196         drawall();
197 }