aewl

view tag.c @ 138:c1185dc7a36e

some cleanups/fixes inspired by Jukka Salmi's feedback
author arg@10ksloc.org
date Fri, 21 Jul 2006 18:34:10 +0200
parents 30d1302dbe3b
children 9b9deafa0508
line source
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"
7 #include <regex.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <sys/types.h>
11 #include <X11/Xutil.h>
13 /* static */
15 typedef struct {
16 const char *pattern;
17 char *tags[TLast];
18 Bool isfloat;
19 } Rule;
21 /* CUSTOMIZE */
22 static Rule rule[] = {
23 /* class:instance tags isfloat */
24 { "Firefox.*", { [Tnet] = "net" }, False },
25 { "Gimp.*", { 0 }, True},
26 };
28 char *tags[TLast] = {
29 [Tfnord] = "fnord",
30 [Tdev] = "dev",
31 [Tnet] = "net",
32 [Twork] = "work",
33 [Tmisc] = "misc",
34 };
36 void (*arrange)(Arg *) = dotile;
38 /* END CUSTOMIZE */
40 /* extern */
42 void
43 appendtag(Arg *arg)
44 {
45 if(!sel)
46 return;
48 sel->tags[arg->i] = tags[arg->i];
49 arrange(NULL);
50 }
52 void
53 dofloat(Arg *arg)
54 {
55 Client *c;
57 for(c = clients; c; c = c->next) {
58 c->ismax = False;
59 if(c->tags[tsel]) {
60 resize(c, True, TopLeft);
61 }
62 else
63 ban(c);
64 }
65 if(sel && !sel->tags[tsel]) {
66 if((sel = getnext(clients, tsel))) {
67 higher(sel);
68 focus(sel);
69 }
70 }
71 drawall();
72 }
74 void
75 dotile(Arg *arg)
76 {
77 int n, i, w, h;
78 Client *c;
80 w = sw - mw;
81 for(n = 0, c = clients; c; c = c->next)
82 if(c->tags[tsel] && !c->isfloat)
83 n++;
85 if(n > 1)
86 h = (sh - bh) / (n - 1);
87 else
88 h = sh - bh;
90 for(i = 0, c = clients; c; c = c->next) {
91 c->ismax = False;
92 if(c->tags[tsel]) {
93 if(c->isfloat) {
94 higher(c);
95 resize(c, True, TopLeft);
96 continue;
97 }
98 if(n == 1) {
99 c->x = sx;
100 c->y = sy + bh;
101 c->w = sw - 2 * c->border;
102 c->h = sh - 2 * c->border - bh;
103 }
104 else if(i == 0) {
105 c->x = sx;
106 c->y = sy + bh;
107 c->w = mw - 2 * c->border;
108 c->h = sh - 2 * c->border - bh;
109 }
110 else if(h > bh) {
111 c->x = sx + mw;
112 c->y = sy + (i - 1) * h + bh;
113 c->w = w - 2 * c->border;
114 c->h = h - 2 * c->border;
115 }
116 else { /* fallback if h < bh */
117 c->x = sx + mw;
118 c->y = sy + bh;
119 c->w = w - 2 * c->border;
120 c->h = sh - 2 * c->border - bh;
121 }
122 resize(c, False, TopLeft);
123 i++;
124 }
125 else
126 ban(c);
127 }
128 if(!sel || (sel && !sel->tags[tsel])) {
129 if((sel = getnext(clients, tsel))) {
130 higher(sel);
131 focus(sel);
132 }
133 }
134 drawall();
135 }
137 Client *
138 getnext(Client *c, unsigned int t)
139 {
140 for(; c && !c->tags[t]; c = c->next);
141 return c;
142 }
144 Client *
145 getprev(Client *c)
146 {
147 for(; c && !c->tags[tsel]; c = c->prev);
148 return c;
149 }
151 void
152 replacetag(Arg *arg)
153 {
154 int i;
156 if(!sel)
157 return;
159 for(i = 0; i < TLast; i++)
160 sel->tags[i] = NULL;
161 appendtag(arg);
162 }
164 void
165 settags(Client *c)
166 {
167 char classinst[256];
168 static unsigned int len = sizeof(rule) / sizeof(rule[0]);
169 unsigned int i, j;
170 regex_t regex;
171 regmatch_t tmp;
172 Bool matched = False;
173 XClassHint ch;
175 if(XGetClassHint(dpy, c->win, &ch)) {
176 snprintf(classinst, sizeof(classinst), "%s:%s",
177 ch.res_class ? ch.res_class : "",
178 ch.res_name ? ch.res_name : "");
179 for(i = 0; !matched && i < len; i++) {
180 if(!regcomp(&regex, rule[i].pattern, 0)) {
181 if(!regexec(&regex, classinst, 1, &tmp, 0)) {
182 for(j = 0; j < TLast; j++) {
183 if(rule[i].tags[j])
184 matched = True;
185 c->tags[j] = rule[i].tags[j];
186 }
187 c->isfloat = rule[i].isfloat;
188 }
189 regfree(&regex);
190 }
191 }
192 if(ch.res_class)
193 XFree(ch.res_class);
194 if(ch.res_name)
195 XFree(ch.res_name);
196 }
197 if(!matched)
198 c->tags[tsel] = tags[tsel];
199 }
201 void
202 togglemode(Arg *arg)
203 {
204 arrange = arrange == dofloat ? dotile : dofloat;
205 arrange(NULL);
206 }
208 void
209 view(Arg *arg)
210 {
211 tsel = arg->i;
212 arrange(NULL);
213 drawall();
214 }