cleaned up settags-handling 50be6c8b
Anselm R. Garbe · 2007-08-18 13:48 4 file(s) · +90 −81
client.c +44 −1
7 7
8 8
/* static */
9 9
10 +
static char config[128];
11 +
10 12
static void
11 13
attachstack(Client *c) {
12 14
	c->snext = stack;
179 181
		XKillClient(dpy, sel->win);
180 182
}
181 183
184 +
Bool
185 +
loadconfig(Client *c) {
186 +
	unsigned int i;
187 +
	Bool result = False;
188 +
	XTextProperty name;
189 +
190 +
	/* check if window has set a property */
191 +
	name.nitems = 0;
192 +
	XGetTextProperty(dpy, c->win, &name, dwmconfig);
193 +
	if(name.nitems && name.encoding == XA_STRING) {
194 +
		strncpy(config, (char *)name.value, sizeof config - 1);
195 +
		config[sizeof config - 1] = '\0';
196 +
		XFree(name.value);
197 +
		for(i = 0; i < ntags && i < sizeof config - 1 && config[i] != '\0'; i++)
198 +
			if((c->tags[i] = config[i] == '1'))
199 +
				result = True;
200 +
		if(i < sizeof config - 1 && config[i] != '\0')
201 +
			c->isfloating = config[i] == '1';
202 +
	}
203 +
	return result;
204 +
}
205 +
182 206
void
183 207
manage(Window w, XWindowAttributes *wa) {
208 +
	unsigned int i;
184 209
	Client *c, *t = NULL;
185 210
	Window trans;
186 211
	Status rettrans;
221 246
	updatetitle(c);
222 247
	if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success))
223 248
		for(t = clients; t && t->win != trans; t = t->next);
224 -
	settags(c, t);
249 +
	if(t)
250 +
		for(i = 0; i < ntags; i++)
251 +
			c->tags[i] = t->tags[i];
252 +
	if(!loadconfig(c))
253 +
		applyrules(c);
225 254
	if(!c->isfloating)
226 255
		c->isfloating = (rettrans == Success) || c->isfixed;
256 +
	saveconfig(c);
227 257
	attach(c);
228 258
	attachstack(c);
229 259
	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); /* some windows require this */
292 322
		configure(c);
293 323
		XSync(dpy, False);
294 324
	}
325 +
}
326 +
327 +
void
328 +
saveconfig(Client *c) {
329 +
	unsigned int i;
330 +
331 +
	for(i = 0; i < ntags && i < sizeof config - 1; i++)
332 +
		config[i] = c->tags[i] ? '1' : '0';
333 +
	if(i < sizeof config - 1)
334 +
		config[i++] = c->isfloating ? '1' : '0';
335 +
	config[i] = '\0';
336 +
	XChangeProperty(dpy, c->win, dwmconfig, XA_STRING, 8,
337 +
			PropModeReplace, (unsigned char *)config, i);
295 338
}
296 339
297 340
void
dwm.h +3 −1
96 96
void detach(Client *c);			/* detaches c from global client list */
97 97
void focus(Client *c);			/* focus c if visible && !NULL, or focus top visible */
98 98
void killclient(const char *arg);	/* kill sel  nicely */
99 +
Bool loadconfig(Client *c);		/* loads client properties */
99 100
void manage(Window w, XWindowAttributes *wa);	/* manage new client */
100 101
void resize(Client *c, int x, int y,
101 102
		int w, int h, Bool sizehints);	/* resize with given coordinates c*/
103 +
void saveconfig(Client *c);		/* saves client properties */
102 104
void unban(Client *c);			/* unbans c */
103 105
void unmanage(Client *c, long state);	/* unmanage c */
104 106
void updatesizehints(Client *c);	/* update the size hint variables of c */
132 134
int xerror(Display *dsply, XErrorEvent *ee);	/* dwm's X error handler */
133 135
134 136
/* tag.c */
137 +
void applyrules(Client *c);		/* applies rules to c */
135 138
void compileregs(void);			/* initialize regexps of rules defined in config.h */
136 139
Bool isvisible(Client *c);		/* returns True if client is visible */
137 -
void settags(Client *c, Client *trans);	/* sets tags of c */
138 140
void tag(const char *arg);		/* tags sel with arg's index */
139 141
void togglefloating(const char *arg);	/* toggles sel between floating/tiled state */
140 142
void toggletag(const char *arg);	/* toggles sel tags with arg's index */
layout.c +9 −9
10 10
} Layout;
11 11
12 12
unsigned int blw = 0;
13 -
static unsigned int sellayout = 0; /* default */
13 +
static unsigned int ltidx = 0; /* default */
14 14
15 15
static void
16 16
floating(void) { /* default floating layout */
36 36
			unban(c);
37 37
		else
38 38
			ban(c);
39 -
	layouts[sellayout].arrange();
39 +
	layouts[ltidx].arrange();
40 40
	focus(NULL);
41 41
	restack();
42 42
}
76 76
const char *
77 77
getsymbol(void)
78 78
{
79 -
	return layouts[sellayout].symbol;
79 +
	return layouts[ltidx].symbol;
80 80
}
81 81
82 82
Bool
83 83
isfloating(void) {
84 -
	return layouts[sellayout].arrange == floating;
84 +
	return layouts[ltidx].arrange == floating;
85 85
}
86 86
87 87
Bool
88 88
isarrange(void (*func)())
89 89
{
90 -
	return func == layouts[sellayout].arrange;
90 +
	return func == layouts[ltidx].arrange;
91 91
}
92 92
93 93
void
94 94
initlayouts(void) {
95 95
	unsigned int i, w;
96 96
97 -
	/* TODO deserialize sellayout if present */
97 +
	/* TODO deserialize ltidx if present */
98 98
	nlayouts = sizeof layouts / sizeof layouts[0];
99 99
	for(blw = i = 0; i < nlayouts; i++) {
100 100
		w = textw(layouts[i].symbol);
143 143
	int i;
144 144
145 145
	if(!arg) {
146 -
		if(++sellayout == nlayouts)
147 -
			sellayout = 0;;
146 +
		if(++ltidx == nlayouts)
147 +
			ltidx = 0;;
148 148
	}
149 149
	else {
150 150
		i = atoi(arg);
151 151
		if(i < 0 || i >= nlayouts)
152 152
			return;
153 -
		sellayout = i;
153 +
		ltidx = i;
154 154
	}
155 155
	if(sel)
156 156
		arrange();
tag.c +34 −70
27 27
static unsigned int nrules = 0;
28 28
static char prop[512];
29 29
30 -
static void
31 -
persistconfig(Client *c) {
32 -
	unsigned int i;
33 -
34 -
	for(i = 0; i < ntags && i < sizeof prop - 1; i++)
35 -
		prop[i] = c->tags[i] ? '1' : '0';
36 -
	if(i < sizeof prop - 1)
37 -
		prop[i++] = c->isfloating ? '1' : '0';
38 -
	prop[i] = '\0';
39 -
	XChangeProperty(dpy, c->win, dwmconfig, XA_STRING, 8,
40 -
			PropModeReplace, (unsigned char *)prop, i);
41 -
}
42 -
43 30
static unsigned int
44 31
idxoftag(const char *tag) {
45 32
	unsigned int i;
53 40
/* extern */
54 41
55 42
void
43 +
applyrules(Client *c) {
44 +
	unsigned int i, j;
45 +
	regmatch_t tmp;
46 +
	Bool matched = False;
47 +
	XClassHint ch = { 0 };
48 +
49 +
	/* rule matching */
50 +
	XGetClassHint(dpy, c->win, &ch);
51 +
	snprintf(prop, sizeof prop, "%s:%s:%s",
52 +
			ch.res_class ? ch.res_class : "",
53 +
			ch.res_name ? ch.res_name : "", c->name);
54 +
	for(i = 0; i < nrules; i++)
55 +
		if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) {
56 +
			c->isfloating = rules[i].isfloating;
57 +
			for(j = 0; regs[i].tagregex && j < ntags; j++) {
58 +
				if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
59 +
					matched = True;
60 +
					c->tags[j] = True;
61 +
				}
62 +
			}
63 +
		}
64 +
	if(ch.res_class)
65 +
		XFree(ch.res_class);
66 +
	if(ch.res_name)
67 +
		XFree(ch.res_name);
68 +
	if(!matched)
69 +
		for(i = 0; i < ntags; i++)
70 +
			c->tags[i] = seltags[i];
71 +
}
72 +
73 +
void
56 74
compileregs(void) {
57 75
	unsigned int i;
58 76
	regex_t *reg;
90 108
}
91 109
92 110
void
93 -
settags(Client *c, Client *trans) {
94 -
	unsigned int i, j;
95 -
	regmatch_t tmp;
96 -
	Bool matched = trans != NULL;
97 -
	XClassHint ch = { 0 };
98 -
	XTextProperty name;
99 -
100 -
	if(matched) {
101 -
		for(i = 0; i < ntags; i++)
102 -
			c->tags[i] = trans->tags[i];
103 -
	}
104 -
	else {
105 -
		/* check if window has set a property */
106 -
		name.nitems = 0;
107 -
		XGetTextProperty(dpy, c->win, &name, dwmconfig);
108 -
		if(name.nitems && name.encoding == XA_STRING) {
109 -
			strncpy(prop, (char *)name.value, sizeof prop - 1);
110 -
			prop[sizeof prop - 1] = '\0';
111 -
			XFree(name.value);
112 -
			for(i = 0; i < ntags && i < sizeof prop - 1 && prop[i] != '\0'; i++)
113 -
				if((c->tags[i] = prop[i] == '1'))
114 -
					matched = True;
115 -
			if(i < sizeof prop - 1 && prop[i] != '\0')
116 -
				c->isfloating = prop[i] == '1';
117 -
		}
118 -
	}
119 -
	if(!matched) {
120 -
		/* rule matching */
121 -
		XGetClassHint(dpy, c->win, &ch);
122 -
		snprintf(prop, sizeof prop, "%s:%s:%s",
123 -
				ch.res_class ? ch.res_class : "",
124 -
				ch.res_name ? ch.res_name : "", c->name);
125 -
		for(i = 0; i < nrules; i++)
126 -
			if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) {
127 -
				c->isfloating = rules[i].isfloating;
128 -
				for(j = 0; regs[i].tagregex && j < ntags; j++) {
129 -
					if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
130 -
						matched = True;
131 -
						c->tags[j] = True;
132 -
					}
133 -
				}
134 -
			}
135 -
		if(ch.res_class)
136 -
			XFree(ch.res_class);
137 -
		if(ch.res_name)
138 -
			XFree(ch.res_name);
139 -
	}
140 -
	if(!matched)
141 -
		for(i = 0; i < ntags; i++)
142 -
			c->tags[i] = seltags[i];
143 -
	persistconfig(c);
144 -
}
145 -
146 -
void
147 111
tag(const char *arg) {
148 112
	unsigned int i;
149 113
154 118
	i = idxoftag(arg);
155 119
	if(i >= 0 && i < ntags)
156 120
		sel->tags[i] = True;
157 -
	persistconfig(sel);
121 +
	saveconfig(sel);
158 122
	arrange();
159 123
}
160 124
165 129
	sel->isfloating = !sel->isfloating;
166 130
	if(sel->isfloating) {
167 131
		resize(sel, sel->x, sel->y, sel->w, sel->h, True);
168 -
		persistconfig(sel);
132 +
		saveconfig(sel);
169 133
	}
170 134
	arrange();
171 135
}
181 145
	for(j = 0; j < ntags && !sel->tags[j]; j++);
182 146
	if(j == ntags)
183 147
		sel->tags[i] = True;
184 -
	persistconfig(sel);
148 +
	saveconfig(sel);
185 149
	arrange();
186 150
}
187 151