removed ugly ban(), extended resize() that it only resets the size if necessary, added border_width commit to manage() 6e22ccf7
Anselm R. Garbe · 2007-02-16 16:38 5 file(s) · +100 −93
client.c +44 −37
158 158
manage(Window w, XWindowAttributes *wa) {
159 159
	Client *c, *t;
160 160
	Window trans;
161 +
	XWindowChanges wc;
161 162
162 163
	c = emallocz(sizeof(Client));
163 164
	c->tags = emallocz(ntags * sizeof(Bool));
187 188
		StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
188 189
	XGetTransientForHint(dpy, c->win, &trans);
189 190
	grabbuttons(c, False);
191 +
	wc.border_width = c->border;
192 +
	XConfigureWindow(dpy, c->win, CWBorderWidth, &wc);
190 193
	XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]);
194 +
	configure(c); /* propagates border_width, if size doesn't change */
191 195
	updatetitle(c);
192 196
	t = getclient(trans);
193 197
	settags(c, t);
198 202
	c->next = clients;
199 203
	c->snext = stack;
200 204
	stack = clients = c;
201 -
	ban(c);
205 +
	c->isbanned = True;
206 +
	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
202 207
	XMapWindow(dpy, c->win);
203 208
	setclientstate(c, NormalState);
204 209
	if(isvisible(c))
207 212
}
208 213
209 214
void
210 -
resize(Client *c, Bool sizehints) {
215 +
resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
211 216
	float actual, dx, dy, max, min;
212 217
	XWindowChanges wc;
213 218
214 -
	if(c->w <= 0 || c->h <= 0)
219 +
	if(w <= 0 || h <= 0)
215 220
		return;
216 221
	if(sizehints) {
217 -
		if(c->minw && c->w < c->minw)
218 -
			c->w = c->minw;
219 -
		if(c->minh && c->h < c->minh)
220 -
			c->h = c->minh;
221 -
		if(c->maxw && c->w > c->maxw)
222 -
			c->w = c->maxw;
223 -
		if(c->maxh && c->h > c->maxh)
224 -
			c->h = c->maxh;
222 +
		if(c->minw && w < c->minw)
223 +
			w = c->minw;
224 +
		if(c->minh && h < c->minh)
225 +
			h = c->minh;
226 +
		if(c->maxw && w > c->maxw)
227 +
			w = c->maxw;
228 +
		if(c->maxh && h > c->maxh)
229 +
			h = c->maxh;
225 230
		/* inspired by algorithm from fluxbox */
226 -
		if(c->minay > 0 && c->maxay && (c->h - c->baseh) > 0) {
227 -
			dx = (float)(c->w - c->basew);
228 -
			dy = (float)(c->h - c->baseh);
231 +
		if(c->minay > 0 && c->maxay && (h - c->baseh) > 0) {
232 +
			dx = (float)(w - c->basew);
233 +
			dy = (float)(h - c->baseh);
229 234
			min = (float)(c->minax) / (float)(c->minay);
230 235
			max = (float)(c->maxax) / (float)(c->maxay);
231 236
			actual = dx / dy;
233 238
				if(actual < min) {
234 239
					dy = (dx * min + dy) / (min * min + 1);
235 240
					dx = dy * min;
236 -
					c->w = (int)dx + c->basew;
237 -
					c->h = (int)dy + c->baseh;
241 +
					w = (int)dx + c->basew;
242 +
					h = (int)dy + c->baseh;
238 243
				}
239 244
				else if(actual > max) {
240 245
					dy = (dx * min + dy) / (max * max + 1);
241 246
					dx = dy * min;
242 -
					c->w = (int)dx + c->basew;
243 -
					c->h = (int)dy + c->baseh;
247 +
					w = (int)dx + c->basew;
248 +
					h = (int)dy + c->baseh;
244 249
				}
245 250
			}
246 251
		}
247 252
		if(c->incw)
248 -
			c->w -= (c->w - c->basew) % c->incw;
253 +
			w -= (w - c->basew) % c->incw;
249 254
		if(c->inch)
250 -
			c->h -= (c->h - c->baseh) % c->inch;
255 +
			h -= (h - c->baseh) % c->inch;
251 256
	}
252 -
	if(c->w == sw && c->h == sh)
257 +
	if(w == sw && h == sh)
253 258
		c->border = 0;
254 259
	else
255 260
		c->border = BORDERPX;
256 261
	/* offscreen appearance fixes */
257 -
	if(c->x > sw)
258 -
		c->x = sw - c->w - 2 * c->border;
259 -
	if(c->y > sh)
260 -
		c->y = sh - c->h - 2 * c->border;
261 -
	if(c->x + c->w + 2 * c->border < sx)
262 -
		c->x = sx;
263 -
	if(c->y + c->h + 2 * c->border < sy)
264 -
		c->y = sy;
265 -
	wc.x = c->x;
266 -
	wc.y = c->y;
267 -
	wc.width = c->w;
268 -
	wc.height = c->h;
269 -
	wc.border_width = c->border;
270 -
	XConfigureWindow(dpy, c->win, CWX | CWY | CWWidth | CWHeight | CWBorderWidth, &wc);
271 -
	configure(c);
272 -
	XSync(dpy, False);
262 +
	if(x > sw)
263 +
		x = sw - w - 2 * c->border;
264 +
	if(y > sh)
265 +
		y = sh - h - 2 * c->border;
266 +
	if(x + w + 2 * c->border < sx)
267 +
		x = sx;
268 +
	if(y + h + 2 * c->border < sy)
269 +
		y = sy;
270 +
	if(c->x != x || c->y != y || c->w != w || c->h != h) {
271 +
		c->x = wc.x = x;
272 +
		c->y = wc.y = y;
273 +
		c->w = wc.width = w;
274 +
		c->h = wc.height = h;
275 +
		wc.border_width = c->border;
276 +
		XConfigureWindow(dpy, c->win, CWX | CWY | CWWidth | CWHeight | CWBorderWidth, &wc);
277 +
		configure(c);
278 +
		XSync(dpy, False);
279 +
	}
273 280
}
274 281
275 282
void
dwm.h +2 −2
99 99
extern Window root, barwin;
100 100
101 101
/* client.c */
102 -
extern void ban(Client *c);			/* ban c */
103 102
extern void configure(Client *c);		/* send synthetic configure event */
104 103
extern void focus(Client *c);			/* focus c, c may be NULL */
105 104
extern Client *getclient(Window w);		/* return client of w */
106 105
extern Bool isprotodel(Client *c);		/* returns True if c->win supports wmatom[WMDelete] */
107 106
extern void killclient(Arg *arg);		/* kill c nicely */
108 107
extern void manage(Window w, XWindowAttributes *wa);	/* manage new client */
109 -
extern void resize(Client *c, Bool sizehints);	/* resize c*/
108 +
extern void resize(Client *c, int x, int y,
109 +
		int w, int h, Bool sizehints);	/* resize c*/
110 110
extern void updatesizehints(Client *c);		/* update the size hint variables of c */
111 111
extern void updatetitle(Client *c);		/* update the name of c */
112 112
extern void unmanage(Client *c);		/* destroy c */
event.c +20 −22
22 22
23 23
static void
24 24
movemouse(Client *c) {
25 -
	int x1, y1, ocx, ocy, di;
25 +
	int x1, y1, ocx, ocy, di, nx, ny;
26 26
	unsigned int dui;
27 27
	Window dummy;
28 28
	XEvent ev;
29 29
30 -
	ocx = c->x;
31 -
	ocy = c->y;
30 +
	ocx = nx = c->x;
31 +
	ocy = ny =  c->y;
32 32
	if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
33 33
			None, cursor[CurMove], CurrentTime) != GrabSuccess)
34 34
		return;
38 38
		XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev);
39 39
		switch (ev.type) {
40 40
		case ButtonRelease:
41 -
			resize(c, True);
42 41
			XUngrabPointer(dpy, CurrentTime);
43 42
			return;
44 43
		case ConfigureRequest:
48 47
			break;
49 48
		case MotionNotify:
50 49
			XSync(dpy, False);
51 -
			c->x = ocx + (ev.xmotion.x - x1);
52 -
			c->y = ocy + (ev.xmotion.y - y1);
53 -
			if(abs(wax + c->x) < SNAP)
54 -
				c->x = wax;
55 -
			else if(abs((wax + waw) - (c->x + c->w + 2 * c->border)) < SNAP)
56 -
				c->x = wax + waw - c->w - 2 * c->border;
57 -
			if(abs(way - c->y) < SNAP)
58 -
				c->y = way;
59 -
			else if(abs((way + wah) - (c->y + c->h + 2 * c->border)) < SNAP)
60 -
				c->y = way + wah - c->h - 2 * c->border;
61 -
			resize(c, False);
50 +
			nx = ocx + (ev.xmotion.x - x1);
51 +
			ny = ocy + (ev.xmotion.y - y1);
52 +
			if(abs(wax + nx) < SNAP)
53 +
				nx = wax;
54 +
			else if(abs((wax + waw) - (nx + c->w + 2 * c->border)) < SNAP)
55 +
				nx = wax + waw - c->w - 2 * c->border;
56 +
			if(abs(way - ny) < SNAP)
57 +
				ny = way;
58 +
			else if(abs((way + wah) - (ny + c->h + 2 * c->border)) < SNAP)
59 +
				ny = way + wah - c->h - 2 * c->border;
60 +
			resize(c, nx, ny, c->w, c->h, False);
62 61
			break;
63 62
		}
64 63
	}
81 80
		XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask , &ev);
82 81
		switch(ev.type) {
83 82
		case ButtonRelease:
84 -
			resize(c, True);
85 83
			XWarpPointer(dpy, None, c->win, 0, 0, 0, 0,
86 84
					c->w + c->border - 1, c->h + c->border - 1);
87 85
			XUngrabPointer(dpy, CurrentTime);
94 92
			break;
95 93
		case MotionNotify:
96 94
			XSync(dpy, False);
97 -
			nw = ev.xmotion.x - ocx - 2 * c->border + 1;
98 -
			c->w = nw > 0 ? nw : 1;
99 -
			nh = ev.xmotion.y - ocy - 2 * c->border + 1;
100 -
			c->h = nh > 0 ? nh : 1;
101 -
			resize(c, True);
95 +
			if((nw = ev.xmotion.x - ocx - 2 * c->border + 1) <= 0)
96 +
				nw = 1;
97 +
			if((nh = ev.xmotion.y - ocy - 2 * c->border + 1) <= 0)
98 +
				nh = 1;
99 +
			resize(c, c->x, c->y, nw, nh, True);
102 100
			break;
103 101
		}
104 102
	}
187 185
			if((ev->value_mask & (CWX | CWY))
188 186
			&& !(ev->value_mask & (CWWidth | CWHeight)))
189 187
				configure(c);
190 -
			resize(c, False);
188 +
			resize(c, c->x, c->y, c->w, c->h, False);
191 189
			if(!isvisible(c))
192 190
				ban(c);
193 191
		}
main.c +2 −1
41 41
cleanup(void) {
42 42
	close(STDIN_FILENO);
43 43
	while(stack) {
44 -
		resize(stack, True);
44 +
		if(stack->isbanned)
45 +
			XMoveWindow(dpy, stack->win, stack->x, stack->y);
45 46
		unmanage(stack);
46 47
	}
47 48
	if(dc.font.set)
view.c +32 −31
20 20
		return;
21 21
22 22
	if((c->ismax = !c->ismax)) {
23 -
		c->rx = c->x; c->x = wax;
24 -
		c->ry = c->y; c->y = way;
25 -
		c->rw = c->w; c->w = waw - 2 * BORDERPX;
26 -
		c->rh = c->h; c->h = wah - 2 * BORDERPX;
27 -
	}
28 -
	else {
29 -
		c->x = c->rx;
30 -
		c->y = c->ry;
31 -
		c->w = c->rw;
32 -
		c->h = c->rh;
23 +
		c->rx = c->x;
24 +
		c->ry = c->y;
25 +
		c->rw = c->w;
26 +
		c->rh = c->h;
27 +
		resize(c, wax, way, waw - 2 * BORDERPX, wah - 2 * BORDERPX, True);
33 28
	}
34 -
	resize(c, True);
29 +
	else
30 +
		resize(c, c->rx, c->ry, c->rw, c->rh, True);
35 31
	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
36 32
}
37 33
56 52
57 53
	for(c = clients; c; c = c->next) {
58 54
		if(isvisible(c)) {
55 +
			if(c->isbanned)
56 +
				XMoveWindow(dpy, c->win, c->x, c->y);
59 57
			c->isbanned = False;
60 -
			resize(c, True);
61 58
		}
62 -
		else
63 -
			ban(c);
59 +
		else {
60 +
			c->isbanned = True;
61 +
			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
62 +
		}
64 63
	}
65 64
	if(!sel || !isvisible(sel)) {
66 65
		for(c = stack; c && !isvisible(c); c = c->snext);
71 70
72 71
void
73 72
dotile(void) {
74 -
	unsigned int i, n, mw, mh, tw, th;
73 +
	unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
75 74
	Client *c;
76 75
77 76
	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
84 83
85 84
	for(i = 0, c = clients; c; c = c->next)
86 85
		if(isvisible(c)) {
86 +
			if(c->isbanned)
87 +
				XMoveWindow(dpy, c->win, c->x, c->y);
87 88
			c->isbanned = False;
88 -
			if(c->isfloat) {
89 -
				resize(c, True);
89 +
			if(c->isfloat)
90 90
				continue;
91 -
			}
92 91
			c->ismax = False;
93 -
			c->x = wax;
94 -
			c->y = way;
92 +
			nx = wax;
93 +
			ny = way;
95 94
			if(i < nmaster) {
96 -
				c->y += i * mh;
97 -
				c->w = mw - 2 * BORDERPX;
98 -
				c->h = mh - 2 * BORDERPX;
95 +
				ny += i * mh;
96 +
				nw = mw - 2 * BORDERPX;
97 +
				nh = mh - 2 * BORDERPX;
99 98
			}
100 99
			else {  /* tile window */
101 -
				c->x += mw;
102 -
				c->w = tw - 2 * BORDERPX;
100 +
				nx += mw;
101 +
				nw = tw - 2 * BORDERPX;
103 102
				if(th > 2 * BORDERPX) {
104 -
					c->y += (i - nmaster) * th;
105 -
					c->h = th - 2 * BORDERPX;
103 +
					ny += (i - nmaster) * th;
104 +
					nh = th - 2 * BORDERPX;
106 105
				}
107 106
				else /* fallback if th <= 2 * BORDERPX */
108 -
					c->h = wah - 2 * BORDERPX;
107 +
					nh = wah - 2 * BORDERPX;
109 108
			}
110 -
			resize(c, False);
109 +
			resize(c, nx, ny, nw, nh, False);
111 110
			i++;
112 111
		}
113 -
		else
114 -
			ban(c);
112 +
		else {
113 +
			c->isbanned = True;
114 +
			XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
115 +
		}
115 116
	if(!sel || !isvisible(sel)) {
116 117
		for(c = stack; c && !isvisible(c); c = c->snext);
117 118
		focus(c);