implemened distinguishing float/managed geometries of clients (works quite well) 58f2fe3f
Anselm R. Garbe · 2006-07-18 12:36 5 file(s) · +105 −78
client.c +68 −48
16 16
{
17 17
	int i;
18 18
19 -
	c->tw = 0;
19 +
	c->bw = 0;
20 20
	for(i = 0; i < TLast; i++)
21 21
		if(c->tags[i])
22 -
			c->tw += textw(c->tags[i]);
23 -
	c->tw += textw(c->name);
24 -
	if(c->tw > c->w)
25 -
		c->tw = c->w + 2;
26 -
	c->tx = c->x + c->w - c->tw + 2;
27 -
	c->ty = c->y;
28 -
	XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
22 +
			c->bw += textw(c->tags[i]);
23 +
	c->bw += textw(c->name);
24 +
	if(c->bw > *c->w)
25 +
		c->bw = *c->w + 2;
26 +
	c->bx = *c->x + *c->w - c->bw + 2;
27 +
	c->by = *c->y;
28 +
	XMoveResizeWindow(dpy, c->title, c->bx, c->by, c->bw, c->bh);
29 29
}
30 30
31 31
static int
39 39
void
40 40
ban(Client *c)
41 41
{
42 -
	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
43 -
	XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
42 +
	XMoveWindow(dpy, c->win, *c->x + 2 * sw, *c->y);
43 +
	XMoveWindow(dpy, c->title, c->bx + 2 * sw, c->by);
44 44
}
45 45
46 46
void
124 124
	case EastGravity:
125 125
	case CenterGravity:
126 126
	case WestGravity:
127 -
		dy = -(c->h / 2) + c->border;
127 +
		dy = -(*c->h / 2) + c->border;
128 128
		break;
129 129
	case SouthEastGravity:
130 130
	case SouthGravity:
131 131
	case SouthWestGravity:
132 -
		dy = -c->h;
132 +
		dy = -(*c->h);
133 133
		break;
134 134
	default:
135 135
		break;
145 145
	case NorthGravity:
146 146
	case CenterGravity:
147 147
	case SouthGravity:
148 -
		dx = -(c->w / 2) + c->border;
148 +
		dx = -(*c->w / 2) + c->border;
149 149
		break;
150 150
	case NorthEastGravity:
151 151
	case EastGravity:
152 152
	case SouthEastGravity:
153 -
		dx = -(c->w + c->border);
153 +
		dx = -(*c->w + c->border);
154 154
		break;
155 155
	default:
156 156
		break;
160 160
		dx = -dx;
161 161
		dy = -dy;
162 162
	}
163 -
	c->x += dx;
164 -
	c->y += dy;
163 +
	*c->x += dx;
164 +
	*c->y += dy;
165 165
}
166 166
167 167
void
198 198
199 199
	c = emallocz(sizeof(Client));
200 200
	c->win = w;
201 -
	c->tx = c->x = wa->x;
202 -
	c->ty = c->y = wa->y;
203 -
	if(c->y < bh)
204 -
		c->ty = c->y += bh;
205 -
	c->tw = c->w = wa->width;
206 -
	c->h = wa->height;
207 -
	c->th = bh;
201 +
	c->bx = c->fx = c->tx = wa->x;
202 +
	c->by = c->fy = c->ty = wa->y;
203 +
	if(c->fy < bh)
204 +
		c->by = c->fy = c->ty += bh;
205 +
	c->bw = c->fw = c->tw = wa->width;
206 +
	c->fh = c->th = wa->height;
207 +
	c->bh = bh;
208 208
	c->border = 1;
209 209
	c->proto = getproto(c->win);
210 210
	setsize(c);
215 215
	twa.background_pixmap = ParentRelative;
216 216
	twa.event_mask = ExposureMask;
217 217
218 -
	c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th,
218 +
	c->title = XCreateWindow(dpy, root, c->bx, c->by, c->bw, c->bh,
219 219
			0, DefaultDepth(dpy, screen), CopyFromParent,
220 220
			DefaultVisual(dpy, screen),
221 221
			CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
222 222
223 -
	settitle(c);
224 223
	settags(c);
225 224
226 225
	c->next = clients;
239 238
		c->isfloat = trans
240 239
			|| ((c->maxw == c->minw) && (c->maxh == c->minh));
241 240
241 +
	setgeom(c);
242 +
	settitle(c);
243 +
242 244
	arrange(NULL);
245 +
243 246
	/* mapping the window now prevents flicker */
244 247
	if(c->tags[tsel]) {
245 248
		XMapRaised(dpy, c->win);
259 262
{
260 263
	if(!sel)
261 264
		return;
262 -
	sel->x = sx;
263 -
	sel->y = sy + bh;
264 -
	sel->w = sw - 2 * sel->border;
265 -
	sel->h = sh - 2 * sel->border - bh;
265 +
	*sel->x = sx;
266 +
	*sel->y = sy + bh;
267 +
	*sel->w = sw - 2 * sel->border;
268 +
	*sel->h = sh - 2 * sel->border - bh;
266 269
	higher(sel);
267 270
	resize(sel, False);
268 271
}
286 289
287 290
	if(inc) {
288 291
		if(c->incw)
289 -
			c->w -= (c->w - c->basew) % c->incw;
292 +
			*c->w -= (*c->w - c->basew) % c->incw;
290 293
		if(c->inch)
291 -
			c->h -= (c->h - c->baseh) % c->inch;
294 +
			*c->h -= (*c->h - c->baseh) % c->inch;
292 295
	}
293 -
	if(c->x > sw) /* might happen on restart */
294 -
		c->x = sw - c->w;
295 -
	if(c->y > sh)
296 -
		c->ty = c->y = sh - c->h;
297 -
	if(c->minw && c->w < c->minw)
298 -
		c->w = c->minw;
299 -
	if(c->minh && c->h < c->minh)
300 -
		c->h = c->minh;
301 -
	if(c->maxw && c->w > c->maxw)
302 -
		c->w = c->maxw;
303 -
	if(c->maxh && c->h > c->maxh)
304 -
		c->h = c->maxh;
296 +
	if(*c->x > sw) /* might happen on restart */
297 +
		*c->x = sw - *c->w;
298 +
	if(*c->y > sh)
299 +
		*c->y = sh - *c->h;
300 +
	if(c->minw && *c->w < c->minw)
301 +
		*c->w = c->minw;
302 +
	if(c->minh && *c->h < c->minh)
303 +
		*c->h = c->minh;
304 +
	if(c->maxw && *c->w > c->maxw)
305 +
		*c->w = c->maxw;
306 +
	if(c->maxh && *c->h > c->maxh)
307 +
		*c->h = c->maxh;
305 308
	resizetitle(c);
306 309
	XSetWindowBorderWidth(dpy, c->win, 1);
307 -
	XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
310 +
	XMoveResizeWindow(dpy, c->win, *c->x, *c->y, *c->w, *c->h);
308 311
	e.type = ConfigureNotify;
309 312
	e.event = c->win;
310 313
	e.window = c->win;
311 -
	e.x = c->x;
312 -
	e.y = c->y;
313 -
	e.width = c->w;
314 -
	e.height = c->h;
314 +
	e.x = *c->x;
315 +
	e.y = *c->y;
316 +
	e.width = *c->w;
317 +
	e.height = *c->h;
315 318
	e.border_width = c->border;
316 319
	e.above = None;
317 320
	e.override_redirect = False;
318 321
	XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&e);
319 322
	XSync(dpy, False);
323 +
}
324 +
325 +
void
326 +
setgeom(Client *c)
327 +
{
328 +
	if((arrange == dotile) && !c->isfloat) {
329 +
		c->x = &c->tx;
330 +
		c->y = &c->ty;
331 +
		c->w = &c->tw;
332 +
		c->h = &c->th;
333 +
	}
334 +
	else {
335 +
		c->x = &c->fx;
336 +
		c->y = &c->fy;
337 +
		c->w = &c->fw;
338 +
		c->h = &c->fh;
339 +
	}
320 340
}
321 341
322 342
void
dwm.h +5 −2
65 65
	char name[256];
66 66
	char *tags[TLast];
67 67
	int proto;
68 -
	int x, y, w, h;
69 -
	int tx, ty, tw, th;
68 +
	int *x, *y, *w, *h; /* current geom */
69 +
	int bx, by, bw, bh; /* title bar */
70 +
	int fx, fy, fw, fh; /* floating geom */
71 +
	int tx, ty, tw, th; /* tiled geom */
70 72
	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
71 73
	int grav;
72 74
	unsigned int border;
120 122
extern void maximize(Arg *arg);
121 123
extern void pop(Client *c);
122 124
extern void resize(Client *c, Bool inc);
125 +
extern void setgeom(Client *c);
123 126
extern void setsize(Client *c);
124 127
extern void settitle(Client *c);
125 128
extern void unmanage(Client *c);
event.c +15 −15
62 62
	unsigned int dui;
63 63
	Window dummy;
64 64
65 -
	ocx = c->x;
66 -
	ocy = c->y;
65 +
	ocx = *c->x;
66 +
	ocy = *c->y;
67 67
	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
68 68
				None, cursor[CurMove], CurrentTime) != GrabSuccess)
69 69
		return;
77 77
			break;
78 78
		case MotionNotify:
79 79
			XSync(dpy, False);
80 -
			c->x = ocx + (ev.xmotion.x - x1);
81 -
			c->y = ocy + (ev.xmotion.y - y1);
80 +
			*c->x = ocx + (ev.xmotion.x - x1);
81 +
			*c->y = ocy + (ev.xmotion.y - y1);
82 82
			resize(c, False);
83 83
			break;
84 84
		case ButtonRelease:
94 94
	XEvent ev;
95 95
	int ocx, ocy;
96 96
97 -
	ocx = c->x;
98 -
	ocy = c->y;
97 +
	ocx = *c->x;
98 +
	ocy = *c->y;
99 99
	if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
100 100
				None, cursor[CurResize], CurrentTime) != GrabSuccess)
101 101
		return;
102 -
	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
102 +
	XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, *c->w, *c->h);
103 103
	for(;;) {
104 104
		XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
105 105
		switch(ev.type) {
109 109
			break;
110 110
		case MotionNotify:
111 111
			XSync(dpy, False);
112 -
			c->w = abs(ocx - ev.xmotion.x);
113 -
			c->h = abs(ocy - ev.xmotion.y);
114 -
			c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w;
115 -
			c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h;
112 +
			*c->w = abs(ocx - ev.xmotion.x);
113 +
			*c->h = abs(ocy - ev.xmotion.y);
114 +
			*c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - *c->w;
115 +
			*c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - *c->h;
116 116
			resize(c, True);
117 117
			break;
118 118
		case ButtonRelease:
187 187
	if((c = getclient(ev->window))) {
188 188
		gravitate(c, True);
189 189
		if(ev->value_mask & CWX)
190 -
			c->x = ev->x;
190 +
			*c->x = ev->x;
191 191
		if(ev->value_mask & CWY)
192 -
			c->y = ev->y;
192 +
			*c->y = ev->y;
193 193
		if(ev->value_mask & CWWidth)
194 -
			c->w = ev->width;
194 +
			*c->w = ev->width;
195 195
		if(ev->value_mask & CWHeight)
196 -
			c->h = ev->height;
196 +
			*c->h = ev->height;
197 197
		if(ev->value_mask & CWBorderWidth)
198 198
			c->border = 1;
199 199
		gravitate(c, False);
main.c +1 −0
261 261
	XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
262 262
263 263
	strcpy(stext, "dwm-"VERSION);
264 +
264 265
	scan();
265 266
266 267
	/* main event loop, reads status text from stdin as well */
tag.c +16 −13
43 43
44 44
	arrange = dofloat;
45 45
	for(c = clients; c; c = c->next) {
46 -
		if(c->tags[tsel])
46 +
		setgeom(c);
47 +
		if(c->tags[tsel]) {
47 48
			resize(c, True);
49 +
		}
48 50
		else
49 51
			ban(c);
50 52
	}
75 77
		h = sh - bh;
76 78
77 79
	for(i = 0, c = clients; c; c = c->next) {
80 +
		setgeom(c);
78 81
		if(c->tags[tsel]) {
79 82
			if(c->isfloat) {
80 83
				higher(c);
82 85
				continue;
83 86
			}
84 87
			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;
88 +
				*c->x = sx;
89 +
				*c->y = sy + bh;
90 +
				*c->w = sw - 2 * c->border;
91 +
				*c->h = sh - 2 * c->border - bh;
89 92
			}
90 93
			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;
94 +
				*c->x = sx;
95 +
				*c->y = sy + bh;
96 +
				*c->w = mw - 2 * c->border;
97 +
				*c->h = sh - 2 * c->border - bh;
95 98
			}
96 99
			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;
100 +
				*c->x = sx + mw;
101 +
				*c->y = sy + (i - 1) * h + bh;
102 +
				*c->w = w - 2 * c->border;
103 +
				*c->h = h - 2 * c->border;
101 104
			}
102 105
			resize(c, False);
103 106
			i++;