implemented setlayout in the way proposed on the ml, split tile() into two functions, a third will follow soon c9170189
Anselm R Garbe · 2008-03-06 18:53 2 file(s) · +109 −103
config.def.h +17 −17
13 13
/* bar position */
14 14
#define BX sx
15 15
#define BY sy
16 -
#define BW MW
16 +
#define BW sw
17 17
18 18
/* window area */
19 19
#define WX 0
20 20
#define WY bh
21 21
#define WW sw
22 -
#define WH sh
22 +
#define WH sh - bh
23 23
24 24
/* master area */
25 -
#define MX sx
26 -
#define MY sy + bh
25 +
#define MX WX
26 +
#define MY WY
27 27
#define MW ((int)(((float)sw) * 0.6))
28 -
#define MH sh - bh
28 +
#define MH WH
29 29
30 30
/* tile area, might be on a different screen */
31 -
#define TX sx + MW
32 -
#define TY sy
33 -
#define TW sw - MW
34 -
#define TH sh
31 +
#define TX MX + MW
32 +
#define TY WY
33 +
#define TW WW - MW
34 +
#define TH WH
35 35
36 36
/* monocle area, might be restricted to a specific screen */
37 -
#define MOX sx
38 -
#define MOY MY
39 -
#define MOW sw
40 -
#define MOH MH
37 +
#define MOX WX
38 +
#define MOY WY
39 +
#define MOW WW
40 +
#define MOH WH
41 41
42 42
/* tagging */
43 43
const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
55 55
#define SNAP			32	/* snap pixel */
56 56
57 57
Layout layouts[] = {
58 -
	/* symbol		function */
59 -
	{ "[]=",		tile }, /* first entry is default */
60 -
	{ "><>",		floating },
61 -
	{ "[M]",		monocle },
58 +
	/* symbol		function	isfloating */
59 +
	{ "[]=",		tile,		False }, /* first entry is default */
60 +
	{ "><>",		floating	True },
61 +
	{ "[M]",		monocle		True },
62 62
};
63 63
64 64
/* key definitions */
dwm.c +92 −86
1 1
/**
2 -
 * TODO
3 -
 * - treat monocle as floating layout, actually otherwise certain monocled windows don't get raised
4 -
 * - use WX, WY, WW, WH for window snapping/resizing/mouse
5 -
 * - MOX, MOY, MOW, MOH should only be used in the case of monocle layout and of n==1 in tiled
6 -
 * - simplify tile()
7 2
 * - allow for vstack
8 3
 */
9 4
/* See LICENSE file for copyright and license details.
67 62
struct Client {
68 63
	char name[256];
69 64
	int x, y, w, h;
70 -
	int rx, ry, rw, rh;
71 65
	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
72 66
	int minax, maxax, minay, maxay;
73 67
	long flags;
105 99
typedef struct {
106 100
	const char *symbol;
107 101
	void (*arrange)(void);
102 +
	Bool isfloating;
108 103
} Layout;
109 104
110 105
typedef struct {
176 171
unsigned int textnw(const char *text, unsigned int len);
177 172
unsigned int textw(const char *text);
178 173
void tile(void);
174 +
unsigned int tilemaster(void);
175 +
void tilevstack(unsigned int n);
179 176
void togglefloating(const char *arg);
180 177
void toggletag(const char *arg);
181 178
void toggleview(const char *arg);
213 210
	[UnmapNotify] = unmapnotify
214 211
};
215 212
Atom wmatom[WMLast], netatom[NetLast];
216 -
Bool dozoom = True;
217 213
Bool otherwm, readin;
218 214
Bool running = True;
219 215
Bool *prevtags;
297 293
ban(Client *c) {
298 294
	if(c->isbanned)
299 295
		return;
300 -
	XMoveWindow(dpy, c->win, c->x + 3 * sw, c->y);
296 +
	XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
301 297
	c->isbanned = True;
302 298
}
303 299
428 424
	if((c = getclient(ev->window))) {
429 425
		if(ev->value_mask & CWBorderWidth)
430 426
			c->border = ev->border_width;
431 -
		if(c->isfixed || c->isfloating || (floating == lt->arrange)) {
427 +
		if(c->isfixed || c->isfloating || lt->isfloating) {
432 428
			if(ev->value_mask & CWX)
433 429
				c->x = sx + ev->x;
434 430
			if(ev->value_mask & CWY)
637 633
floating(void) { /* default floating layout */
638 634
	Client *c;
639 635
640 -
	dozoom = False;
641 636
	for(c = clients; c; c = c->next)
642 637
		if(isvisible(c))
643 638
			resize(c, c->x, c->y, c->w, c->h, True);
650 645
	if(sel && sel != c) {
651 646
		grabbuttons(sel, False);
652 647
		XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]);
653 -
		if(lt->arrange == monocle)
654 -
			resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
655 648
	}
656 649
	if(c) {
657 650
		detachstack(c);
658 651
		attachstack(c);
659 652
		grabbuttons(c, True);
660 -
		if(lt->arrange == monocle) {
661 -
			if(sel != c) {
662 -
				c->rx = c->x;
663 -
				c->ry = c->y;
664 -
				c->rw = c->w;
665 -
				c->rh = c->h;
666 -
			}
667 -
			resize(c, MOX, MOY, MOW, MOH, RESIZEHINTS);
668 -
		}
669 653
	}
670 654
	sel = c;
671 655
	if(c) {
987 971
	c->tags = emallocz(TAGSZ);
988 972
	c->win = w;
989 973
990 -
	c->x = c->rx = wa->x + sx;
991 -
	c->y = c->ry = wa->y + sy;
992 -
	c->w = c->rw = wa->width;
993 -
	c->h = c->rh = wa->height;
974 +
	/* geometry */
975 +
	c->x = wa->x;
976 +
	c->y = wa->y;
977 +
	c->w = wa->width;
978 +
	c->h = wa->height;
994 979
	c->oldborder = wa->border_width;
995 -
996 980
	if(c->w == sw && c->h == sh) {
997 981
		c->x = sx;
998 982
		c->y = sy;
999 983
		c->border = wa->border_width;
1000 984
	}
1001 985
	else {
1002 -
		if(c->x + c->w + 2 * c->border > sx + sw)
1003 -
			c->x = sx + sw - c->w - 2 * c->border;
1004 -
		if(c->y + c->h + 2 * c->border > sy + sh)
1005 -
			c->y = sy + sh - c->h - 2 * c->border;
1006 -
		if(c->x < sx)
1007 -
			c->x = sx;
1008 -
		if(c->y < sy)
1009 -
			c->y = sy;
986 +
		if(c->x + c->w + 2 * c->border > WX + WW)
987 +
			c->x = WX + WW - c->w - 2 * c->border;
988 +
		if(c->y + c->h + 2 * c->border > WY + WH)
989 +
			c->y = WY + WH - c->h - 2 * c->border;
990 +
		if(c->x < WX)
991 +
			c->x = WX;
992 +
		if(c->y < WY)
993 +
			c->y = WY;
1010 994
		c->border = BORDERPX;
1011 995
	}
996 +
1012 997
	wc.border_width = c->border;
1013 998
	XConfigureWindow(dpy, w, CWBorderWidth, &wc);
1014 999
	XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
1057 1042
}
1058 1043
1059 1044
void
1060 -
monocle(void) {
1061 -
	dozoom = False;
1045 +
monocle(void) { 
1046 +
	Client *c;
1047 +
1048 +
	for(c = clients; c; c = c->next)
1049 +
		if(isvisible(c))
1050 +
			resize(c, MOX, MOY, MOW, MOH, RESIZEHINTS);
1062 1051
}
1063 1052
1064 1053
void
1089 1078
			XSync(dpy, False);
1090 1079
			nx = ocx + (ev.xmotion.x - x1);
1091 1080
			ny = ocy + (ev.xmotion.y - y1);
1092 -
			if(abs(sx - nx) < SNAP)
1093 -
				nx = sx;
1094 -
			else if(abs((sx + sw) - (nx + c->w + 2 * c->border)) < SNAP)
1095 -
				nx = sx + sw - c->w - 2 * c->border;
1096 -
			if(abs(sy - ny) < SNAP)
1097 -
				ny = sy;
1098 -
			else if(abs((sy + sh) - (ny + c->h + 2 * c->border)) < SNAP)
1099 -
				ny = sy + sh - c->h - 2 * c->border;
1100 -
			if(!c->isfloating && (lt->arrange != floating) && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP))
1081 +
			if(abs(WX - nx) < SNAP)
1082 +
				nx = WX;
1083 +
			else if(abs((WX + WW) - (nx + c->w + 2 * c->border)) < SNAP)
1084 +
				nx = WX + WW - c->w - 2 * c->border;
1085 +
			if(abs(WY - ny) < SNAP)
1086 +
				ny = WY;
1087 +
			else if(abs((WY + WH) - (ny + c->h + 2 * c->border)) < SNAP)
1088 +
				ny = WY + WH - c->h - 2 * c->border;
1089 +
			if(!c->isfloating && !lt->isfloating && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP))
1101 1090
				togglefloating(NULL);
1102 -
			if((lt->arrange == floating) || c->isfloating)
1091 +
			if((lt->isfloating) || c->isfloating)
1103 1092
				resize(c, nx, ny, c->w, c->h, False);
1104 1093
			break;
1105 1094
		}
1258 1247
				nw = 1;
1259 1248
			if((nh = ev.xmotion.y - ocy - 2 * c->border + 1) <= 0)
1260 1249
				nh = 1;
1261 -
			if(!c->isfloating && (lt->arrange != floating) && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP))
1250 +
			if(!c->isfloating && !lt->isfloating && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP))
1262 1251
				togglefloating(NULL);
1263 -
			if((lt->arrange == floating) || c->isfloating)
1252 +
			if((lt->isfloating) || c->isfloating)
1264 1253
				resize(c, c->x, c->y, nw, nh, True);
1265 1254
			break;
1266 1255
		}
1276 1265
	drawbar();
1277 1266
	if(!sel)
1278 1267
		return;
1279 -
	if(sel->isfloating || (lt->arrange == floating))
1268 +
	if(sel->isfloating || lt->isfloating)
1280 1269
		XRaiseWindow(dpy, sel->win);
1281 -
	if(lt->arrange != floating) {
1270 +
	if(!lt->isfloating) {
1282 1271
		wc.stack_mode = Below;
1283 1272
		wc.sibling = barwin;
1284 1273
		if(!sel->isfloating) {
1393 1382
1394 1383
void
1395 1384
setlayout(const char *arg) {
1385 +
	static Layout *revert = 0;
1396 1386
	unsigned int i;
1397 1387
1398 1388
	if(!arg)
1402 1392
			break;
1403 1393
	if(i == LENGTH(layouts))
1404 1394
		return;
1405 -
	lt = &layouts[i];
1395 +
	if(revert && &layouts[i] == lt)
1396 +
		lt = revert;
1397 +
	else {
1398 +
		revert = lt;
1399 +
		lt = &layouts[i];
1400 +
	}
1406 1401
	if(sel)
1407 1402
		arrange();
1408 1403
	else
1545 1540
}
1546 1541
1547 1542
void
1548 -
tile(void) {
1549 -
	unsigned int i, n, nx, ny, nw, nh, mw, th;
1543 +
tileresize(Client *c, int x, int y, int w, int h) {
1544 +
	resize(c, x, y, w, h, RESIZEHINTS);
1545 +
	if((RESIZEHINTS) && ((c->h < bh) || (c->h > h) || (c->w < bh) || (c->w > w)))
1546 +
		/* client doesn't accept size constraints */
1547 +
		resize(c, x, y, w, h, False);
1548 +
}
1549 +
1550 +
unsigned int
1551 +
tilemaster(void) {
1552 +
	unsigned int n;
1550 1553
	Client *c, *mc;
1551 1554
1552 -
	dozoom = True;
1553 -
	nx = MX;
1554 -
	ny = MY;
1555 -
	nw = 0;
1556 -
	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
1555 +
	for(n = 0, mc = c = nexttiled(clients); c; c = nexttiled(c->next))
1557 1556
		n++;
1557 +
	if(n == 0)
1558 +
		return 0;
1559 +
	if(n == 1)
1560 +
		tileresize(mc, MOX, MOY, (MOW) - 2 * mc->border, (MOH) - 2 * mc->border);
1561 +
	else
1562 +
		tileresize(mc, MX, MY, (MW) - 2 * mc->border, (MH) - 2 * mc->border);
1563 +
	return n - 1;
1564 +
}
1558 1565
1559 -
	/* window geoms */
1560 -
	mw = (n == 1) ? MOW : MW;
1561 -
	th = (n > 1) ? TH / (n - 1) : 0;
1562 -
	if(n > 1 && th < bh)
1563 -
		th = TH;
1566 +
void
1567 +
tilevstack(unsigned int n) {
1568 +
	int i, y, h;
1569 +
	Client *c;
1570 +
1571 +
	if(n == 0)
1572 +
		return;
1573 +
1574 +
	y = TY;
1575 +
	h = (TH) / n;
1576 +
	if(h < bh)
1577 +
		h = TH;
1564 1578
1565 -
	for(i = 0, c = mc = nexttiled(clients); c; c = nexttiled(c->next)) {
1566 -
		if(i == 0) { /* master */
1567 -
			nw = mw - 2 * c->border;
1568 -
			nh = MH - 2 * c->border;
1569 -
		}
1570 -
		else {  /* tile window */
1571 -
			if(i == 1) {
1572 -
				ny = TY;
1573 -
				nx = TX;
1574 -
				nw = TW - 2 * c->border;
1575 -
			}
1576 -
			if(i + 1 == n) /* remainder */
1577 -
				nh = (TY + TH) - ny - 2 * c->border;
1579 +
	for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++)
1580 +
		if(i > 0) {
1581 +
			if(i > 1 && i == n) /* remainder */
1582 +
				tileresize(c, TX, y, (TW) - 2 * c->border,
1583 +
				              ((TY) + (TH)) - y - 2 * c->border);
1578 1584
			else
1579 -
				nh = th - 2 * c->border;
1585 +
				tileresize(c, TX, y, (TW) - 2 * c->border,
1586 +
				              h - 2 * c->border);
1587 +
			if(h != TH)
1588 +
				y = c->y + c->h + 2 * c->border;
1580 1589
		}
1581 -
		resize(c, nx, ny, nw, nh, RESIZEHINTS);
1582 -
		if((RESIZEHINTS) && ((c->h < bh) || (c->h > nh) || (c->w < bh) || (c->w > nw)))
1583 -
			/* client doesn't accept size constraints */
1584 -
			resize(c, nx, ny, nw, nh, False);
1585 -
		if(n > 1 && th != TH)
1586 -
			ny = c->y + c->h + 2 * c->border;
1587 -
		i++;
1588 -
	}
1590 +
}
1591 +
1592 +
void
1593 +
tile(void) {
1594 +
	tilevstack(tilemaster());
1589 1595
}
1590 1596
1591 1597
void
1796 1802
zoom(const char *arg) {
1797 1803
	Client *c = sel;
1798 1804
1799 -
	if(!sel || !dozoom || sel->isfloating)
1805 +
	if(!sel || lt->isfloating || sel->isfloating)
1800 1806
		return;
1801 1807
	if(c == nexttiled(clients))
1802 1808
		if(!(c = nexttiled(c->next)))