implemented ratio tile as described on the mailinglist e461e609
Anselm R. Garbe · 2007-08-03 19:23 4 file(s) · +73 −44
config.arg.h +5 −5
30 30
	{ "[]=",		tile }, /* first entry is default */ \
31 31
	{ "><>",		floating }, \
32 32
};
33 -
#define MASTERWIDTH		600		/* master width per thousand */
34 -
#define NMASTER			1		/* clients in master area */
35 -
#define SNAP			32		/* snap pixel */
33 +
#define NMASTER			1	/* clients in master area */
34 +
#define RATIO			.8	/* ratio of tile */
35 +
#define SNAP			32	/* snap pixel */
36 36
37 37
/* key definitions */
38 38
#define MODKEY			Mod1Mask
46 46
		"exec urxvtcd -tr -bg '#222' -fg '#eee' -cr '#eee' +sb -fn '"FONT"'" }, \
47 47
	{ MODKEY,			XK_space,	setlayout,	NULL }, \
48 48
	{ MODKEY,			XK_b,		togglebar,	NULL }, \
49 -
	{ MODKEY,			XK_h,		incmasterw,	"-32" }, \
50 -
	{ MODKEY,			XK_l,		incmasterw,	"32" }, \
49 +
	{ MODKEY,			XK_h,		incratio,	".1" }, \
50 +
	{ MODKEY,			XK_l,		incratio,	"-.1" }, \
51 51
	{ MODKEY|ShiftMask,		XK_j,		incnmaster,	"1" }, \
52 52
	{ MODKEY|ShiftMask,		XK_k,		incnmaster,	"-1" }, \
53 53
	{ MODKEY,			XK_j,		focusclient,	"1" }, \
config.default.h +5 −5
31 31
	{ "[]=",		tile }, /* first entry is default */ \
32 32
	{ "><>",		floating }, \
33 33
};
34 -
#define MASTERWIDTH		600		/* master width per thousand */
35 -
#define NMASTER			1		/* clients in master area */
36 -
#define SNAP			32		/* snap pixel */
34 +
#define NMASTER			1	/* clients in master area */
35 +
#define RATIO			.8	/* ratio of tile */
36 +
#define SNAP			32	/* snap pixel */
37 37
38 38
/* key definitions */
39 39
#define MODKEY			Mod1Mask
44 44
	{ MODKEY,			XK_p,		spawn, 		"exe=`dmenu_path | dmenu` && exec $exe" }, \
45 45
	{ MODKEY,			XK_space,	setlayout,	NULL }, \
46 46
	{ MODKEY,			XK_b,		togglebar,	NULL }, \
47 -
	{ MODKEY,			XK_h,		incmasterw,	"-32" }, \
48 -
	{ MODKEY,			XK_l,		incmasterw,	"32" }, \
47 +
	{ MODKEY,			XK_h,		incratio,	".1" }, \
48 +
	{ MODKEY,			XK_l,		incratio,	"-.1" }, \
49 49
	{ MODKEY|ShiftMask,		XK_j,		incnmaster,	"1" }, \
50 50
	{ MODKEY|ShiftMask,		XK_k,		incnmaster,	"-1" }, \
51 51
	{ MODKEY,			XK_j,		focusclient,	"1" }, \
dwm.h +2 −1
44 44
typedef struct Client Client;
45 45
struct Client {
46 46
	char name[256];
47 +
	float scale;
47 48
	int x, y, w, h;
48 49
	int rx, ry, rw, rh; /* revert geometry */
49 50
	int basew, baseh, incw, inch, maxw, maxh, minw, minh;
122 123
/* layout.c */
123 124
void floating(void);			/* arranges all windows floating */
124 125
void focusclient(const char *arg);	/* focuses next(1)/previous(-1) visible client */
125 -
void incmasterw(const char *arg);	/* increments the master width with arg's index value */
126 +
void incratio(const char *arg);		/* increments the tile ratio with arg's value */
126 127
void incnmaster(const char *arg);	/* increments nmaster with arg's index value */
127 128
void initlayouts(void);			/* initialize layout array */
128 129
Client *nexttiled(Client *c);		/* returns tiled successor of c */
layout.c +61 −33
1 1
/* See LICENSE file for copyright and license details. */
2 2
#include "dwm.h"
3 +
#include <stdio.h>
3 4
#include <stdlib.h>
4 5
5 6
unsigned int blw = 0;
7 8
8 9
/* static */
9 10
11 +
static double ratio = RATIO;
10 12
static unsigned int nlayouts = 0;
11 -
static unsigned int masterw = MASTERWIDTH;
12 13
static unsigned int nmaster = NMASTER;
13 14
15 +
static double // simple pow()
16 +
spow(double x, double y)
17 +
{
18 +
	if(y == 0)
19 +
		return 1;
20 +
	while(--y)
21 +
		x *= x;
22 +
	return x;
23 +
}
24 +
14 25
static void
15 26
tile(void) {
16 -
	unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th;
27 +
	double mscale = 0, tscale = 0, sum = 0;
28 +
	unsigned int i, n, nx, ny, nw, nh, mw, tw;
17 29
	Client *c;
18 30
19 31
	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
20 32
		n++;
21 -
	/* window geoms */
22 -
	mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1);
23 -
	mw = (n > nmaster) ? (waw * masterw) / 1000 : waw;
24 -
	th = (n > nmaster) ? wah / (n - nmaster) : 0;
33 +
34 +
	mw = (n <= nmaster) ? waw :  waw / (1 + ratio);
25 35
	tw = waw - mw;
26 36
37 +
	if(n > 0) {
38 +
		if(n < nmaster) {
39 +
			for(i = 0; i < n; i++)
40 +
				sum += spow(ratio, i);
41 +
			mscale = wah / sum;
42 +
		}
43 +
		else {
44 +
			for(i = 0; i < nmaster; i++)
45 +
				sum += spow(ratio, i);
46 +
			mscale = wah / sum;
47 +
			for(sum = 0, i = 0; i < (n - nmaster); i++)
48 +
				sum += spow(ratio, i);
49 +
			tscale = wah / sum;
50 +
		}
51 +
	}
52 +
	nx = wax;
53 +
	ny = way;
27 54
	for(i = 0, c = clients; c; c = c->next)
28 55
		if(isvisible(c)) {
29 56
			unban(c);
30 57
			if(c->isfloating)
31 58
				continue;
32 59
			c->ismax = False;
33 -
			nx = wax;
34 -
			ny = way;
35 -
			if(i < nmaster) {
36 -
				ny += i * mh;
60 +
			if(i < nmaster) { /* master window */
37 61
				nw = mw - 2 * c->border;
38 -
				nh = mh;
39 -
				if(i + 1 == (n < nmaster ? n : nmaster)) /* remainder */
40 -
					nh = wah - mh * i;
41 -
				nh -= 2 * c->border;
62 +
				if(i + 1 == n || i + 1 == nmaster)
63 +
					nh = (way + wah) - ny - (2 * c->border);
64 +
				else
65 +
					nh = (mscale * spow(ratio, i)) - (2 * c->border);
42 66
			}
43 -
			else {  /* tile window */
44 -
				nx += mw;
45 -
				nw = tw - 2 * c->border;
46 -
				if(th > 2 * c->border) {
47 -
					ny += (i - nmaster) * th;
48 -
					nh = th;
49 -
					if(i + 1 == n) /* remainder */
50 -
						nh = wah - th * (i - nmaster);
51 -
					nh -= 2 * c->border;
67 +
			else { /* tile window */
68 +
				if(i == nmaster) {
69 +
					ny = way;
70 +
					nx = wax + mw;
52 71
				}
53 -
				else /* fallback if th <= 2 * c->border */
54 -
					nh = wah - 2 * c->border;
72 +
				nw = tw - 2 * c->border;
73 +
				if(i + 1 == n)
74 +
					nh = (way + wah) - ny - (2 * c->border);
75 +
				else
76 +
					nh = (tscale * spow(ratio, i - nmaster)) - (2 * c->border);
77 +
			}
78 +
			if(nh < bh) {
79 +
				nh = bh;
80 +
				ny = way + wah - nh;
55 81
			}
56 82
			resize(c, nx, ny, nw, nh, False);
83 +
			ny += nh;
57 84
			i++;
58 85
		}
59 86
		else
106 133
}
107 134
108 135
void
109 -
incmasterw(const char *arg) {
110 -
	int i;
136 +
incratio(const char *arg) {
137 +
	double delta;
138 +
111 139
	if(lt->arrange != tile)
112 140
		return;
113 141
	if(!arg)
114 -
		masterw = MASTERWIDTH;
142 +
		ratio = RATIO;
115 143
	else {
116 -
		i = atoi(arg);
117 -
		if(waw * (masterw + i) / 1000 >= waw - 2 * BORDERPX 
118 -
		|| waw * (masterw + i) / 1000 <= 2 * BORDERPX)
119 -
			return;
120 -
		masterw += i;
144 +
		if(1 == sscanf(arg, "%lf", &delta)) {
145 +
			if(delta + ratio < .1 || delta + ratio > 1.9)
146 +
				return;
147 +
			ratio += delta;
148 +
		}
121 149
	}
122 150
	lt->arrange();
123 151
}