JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
ordered variables in structs and source files alphabetically
[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))) {
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))) {
110                         higher(sel);
111                         focus(sel);
112                 }
113         }
114         drawall();
115 }
116
117 Client *
118 getnext(Client *c)
119 {
120         for(; c && !c->tags[tsel]; c = c->next);
121         return c;
122 }
123
124 void
125 replacetag(Arg *arg)
126 {
127         int i;
128         if(!sel)
129                 return;
130
131         for(i = 0; i < TLast; i++)
132                 sel->tags[i] = NULL;
133         appendtag(arg);
134 }
135
136 void
137 settags(Client *c)
138 {
139         XClassHint ch;
140         static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0;
141         unsigned int i, j;
142         Bool matched = False;
143
144         if(!len) {
145                 c->tags[tsel] = tags[tsel];
146                 return;
147         }
148
149         if(XGetClassHint(dpy, c->win, &ch)) {
150                 if(ch.res_class && ch.res_name) {
151                         for(i = 0; i < len; i++)
152                                 if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class))
153                                         && !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance)))
154                                 {
155                                         for(j = 0; j < TLast; j++)
156                                                 c->tags[j] = rule[i].tags[j];
157                                         c->isfloat = rule[i].isfloat;
158                                         matched = True;
159                                         break;
160                                 }
161                 }
162                 if(ch.res_class)
163                         XFree(ch.res_class);
164                 if(ch.res_name)
165                         XFree(ch.res_name);
166         }
167
168         if(!matched)
169                 c->tags[tsel] = tags[tsel];
170 }
171
172 void
173 view(Arg *arg)
174 {
175         tsel = arg->i;
176         arrange(NULL);
177         drawall();
178 }