diff options
Diffstat (limited to 'sys/cmd/dvtm/hook.c')
-rw-r--r-- | sys/cmd/dvtm/hook.c | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/sys/cmd/dvtm/hook.c b/sys/cmd/dvtm/hook.c new file mode 100644 index 0000000..da3946c --- /dev/null +++ b/sys/cmd/dvtm/hook.c @@ -0,0 +1,346 @@ +#include "dvtm.h" + +void +fibonacci(int s) +{ + unsigned int nx, ny, nw, nnw, nh, nnh, i, n, mod; + Client *c; + + for (n = 0, c = nextvisible(clients); c; c = nextvisible(c->next)) + if (!c->minimized) + n++; + + /* initial position and dimensions */ + nx = wax; + ny = way; + nw = (n == 1) ? waw : screen.mfact * waw; + /* don't waste space dviding by 2 doesn't work for odd numbers + * plus we need space for the border too. therefore set up these + * variables for the next new width/height + */ + nnw = waw - nw - 1; + nnh = nh = wah; + + /* set the mod factor, 2 for dwindle, 4 for spiral */ + mod = s ? 4 : 2; + + for (i = 0, c = nextvisible(clients); c; c = nextvisible(c->next)) { + if (c->minimized) + continue; + /* dwindle: even case, spiral: case 0 */ + if (i % mod == 0) { + if (i) { + if (s) { + nh = nnh; + ny -= nh; + } else { + ny += nh; + nh = nnh; + } + /* don't adjust the width for the last client */ + if (i < n - 1) { + nw /= 2; + nnw -= nw + 1; + } + mvaddch(ny, nx - 1, ACS_LTEE); + } + } else if (i % mod == 1) { /* dwindle: odd case, spiral: case 1 */ + nx += nw; + mvvline(ny, nx, ACS_VLINE, nh); + mvaddch(ny, nx, ACS_TTEE); + ++nx; + nw = nnw; + /* don't adjust the height for the last client */ + if (i < n - 1) { + nh /= 2; + nnh -= nh; + } + } else if (i % mod == 2 && s) { /* spiral: case 2 */ + ny += nh; + nh = nnh; + /* don't adjust the width for the last client */ + if (i < n - 1) { + nw /= 2; + nnw -= nw + 1; + nx += nnw; + mvvline(ny, nx, ACS_VLINE, nh); + mvaddch(ny, nx, ACS_TTEE); + ++nx; + } else { + mvaddch(ny, nx - 1, ACS_LTEE); + } + } else if (s) { /* spiral: case 3 */ + nw = nnw; + nx -= nw + 1; /* border */ + /* don't adjust the height for the last client */ + if (i < n - 1) { + nh /= 2; + nnh -= nh; + ny += nnh; + } + mvaddch(ny, nx - 1, ACS_LTEE); + } + + resize(c, nx, ny, nw, nh); + i++; + } +} + + +void +spiral(void) +{ + fibonacci(1); +} + +void +dwindle(void) +{ + fibonacci(0); +} + +void +fullscreen(void) +{ + for (Client *c = nextvisible(clients); c; c = nextvisible(c->next)) + resize(c, wax, way, waw, wah); +} + +void +grid(void) +{ + unsigned int i, n, nx, ny, nw, nh, aw, ah, cols, rows; + Client *c; + + for (n = 0, c = nextvisible(clients); c; c = nextvisible(c->next)) + if (!c->minimized) + n++; + /* grid dimensions */ + for (cols = 0; cols <= n / 2; cols++) + if (cols * cols >= n) + break; + rows = (cols && (cols - 1) * cols >= n) ? cols - 1 : cols; + /* window geoms (cell height/width) */ + nh = wah / (rows ? rows : 1); + nw = waw / (cols ? cols : 1); + for (i = 0, c = nextvisible(clients); c; c = nextvisible(c->next)) { + if (c->minimized) + continue; + /* if there are less clients in the last row than normal adjust the + * split rate to fill the empty space */ + if (rows > 1 && i == (rows * cols) - cols && (n - i) <= (n % cols)) + nw = waw / (n - i); + nx = (i % cols) * nw + wax; + ny = (i / cols) * nh + way; + /* adjust height/width of last row/column's windows */ + ah = (i >= cols * (rows - 1)) ? wah - nh * rows : 0; + /* special case if there are less clients in the last row */ + if (rows > 1 && i == n - 1 && (n - i) < (n % cols)) + /* (n % cols) == number of clients in the last row */ + aw = waw - nw * (n % cols); + else + aw = ((i + 1) % cols == 0) ? waw - nw * cols : 0; + if (i % cols) { + mvvline(ny, nx, ACS_VLINE, nh + ah); + /* if we are on the first row, or on the last one and there are fewer clients + * than normal whose border does not match the line above, print a top tree char + * otherwise a plus sign. */ + if (i <= cols + || (i >= rows * cols - cols && n % cols + && (cols - (n % cols)) % 2)) + mvaddch(ny, nx, ACS_TTEE); + else + mvaddch(ny, nx, ACS_PLUS); + nx++, aw--; + } + resize(c, nx, ny, nw + aw, nh + ah); + i++; + } +} + +void +tile(void) +{ + unsigned int i, n, nx, ny, nw, nh, m, mw, mh, th; + Client *c; + + for (n = 0, c = nextvisible(clients); c; c = nextvisible(c->next)) + if (!c->minimized) + n++; + + m = MAX(1, MIN(n, screen.nmaster)); + mw = n == m ? waw : screen.mfact * waw; + mh = wah / m; + th = n == m ? 0 : wah / (n - m); + nx = wax; + ny = way; + + for (i = 0, c = nextvisible(clients); c; c = nextvisible(c->next)) { + if (c->minimized) + continue; + if (i < m) { /* master */ + nw = mw; + nh = (i < m - 1) ? mh : (way + wah) - ny; + } else { /* tile window */ + if (i == m) { + ny = way; + nx += mw; + mvvline(ny, nx, ACS_VLINE, wah); + mvaddch(ny, nx, ACS_TTEE); + nx++; + nw = waw - mw -1; + } + nh = (i < n - 1) ? th : (way + wah) - ny; + if (i > m) + mvaddch(ny, nx - 1, ACS_LTEE); + } + resize(c, nx, ny, nw, nh); + ny += nh; + i++; + } + + /* Fill in nmaster intersections */ + if (n > m) { + ny = way + mh; + for (i = 1; i < m; i++) { + mvaddch(ny, nx - 1, ((ny - 1) % th ? ACS_RTEE : ACS_PLUS)); + ny += mh; + } + } +} + +void +tstack(void) +{ + unsigned int i, n, nx, ny, nw, nh, m, mw, mh, tw; + Client *c; + + for (n = 0, c = nextvisible(clients); c; c = nextvisible(c->next)) + if (!c->minimized) + n++; + + m = MAX(1, MIN(n, screen.nmaster)); + mh = n == m ? wah : screen.mfact * wah; + mw = waw / m; + tw = n == m ? 0 : waw / (n - m); + nx = wax; + ny = way + wah - mh; + + for (i = 0, c = nextvisible(clients); c; c = nextvisible(c->next)) { + if (c->minimized) + continue; + if (i < m) { /* master */ + if (i > 0) { + mvvline(ny, nx, ACS_VLINE, nh); + mvaddch(ny, nx, ACS_TTEE); + nx++; + } + nh = mh; + nw = (i < m - 1) ? mw : (wax + waw) - nx; + } else { /* tile window */ + if (i == m) { + nx = wax; + ny = way; + nh = (way + wah) - ny - mh; + } + if (i > m) { + mvvline(ny, nx, ACS_VLINE, nh); + mvaddch(ny, nx, ACS_TTEE); + nx++; + } + nw = (i < n - 1) ? tw : (wax + waw) - nx; + } + resize(c, nx, ny, nw, nh); + nx += nw; + i++; + } +} + +void +bstack(void) +{ + unsigned int i, n, nx, ny, nw, nh, m, mw, mh, tw; + Client *c; + + for (n = 0, c = nextvisible(clients); c; c = nextvisible(c->next)) + if (!c->minimized) + n++; + + m = MAX(1, MIN(n, screen.nmaster)); + mh = n == m ? wah : screen.mfact * wah; + mw = waw / m; + tw = n == m ? 0 : waw / (n - m); + nx = wax; + ny = way; + + for (i = 0, c = nextvisible(clients); c; c = nextvisible(c->next)) { + if (c->minimized) + continue; + if (i < m) { /* master */ + if (i > 0) { + mvvline(ny, nx, ACS_VLINE, nh); + mvaddch(ny, nx, ACS_TTEE); + nx++; + } + nh = mh; + nw = (i < m - 1) ? mw : (wax + waw) - nx; + } else { /* tile window */ + if (i == m) { + nx = wax; + ny += mh; + nh = (way + wah) - ny; + } + if (i > m) { + mvvline(ny, nx, ACS_VLINE, nh); + mvaddch(ny, nx, ACS_TTEE); + nx++; + } + nw = (i < n - 1) ? tw : (wax + waw) - nx; + } + resize(c, nx, ny, nw, nh); + nx += nw; + i++; + } + + /* Fill in nmaster intersections */ + if (n > m) { + nx = wax; + for (i = 0; i < m; i++) { + if (i > 0) { + mvaddch(ny, nx, ACS_PLUS); + nx++; + } + nw = (i < m - 1) ? mw : (wax + waw) - nx; + nx += nw; + } + } +} + +/* A vertical stack layout, all windows have the full screen width. */ +void +vstack(void) +{ + unsigned int i, n, ny, nh, m, mh, th; + Client *c; + + for (n = 0, c = nextvisible(clients); c; c = nextvisible(c->next)) + if (!c->minimized) + n++; + + m = MAX(1, MIN(n, screen.nmaster)); + mh = (n == m ? wah : screen.mfact * wah); + th = n == m ? 0 : (wah - mh) / (n - m); + ny = way; + + for (i = 0, c = nextvisible(clients); c; c = nextvisible(c->next)) { + if (c->minimized) + continue; + if (i < m) /* master */ + nh = (i < m - 1) ? mh / m : (way + mh) - ny; + else /* tile window */ + nh = (i < n - 1) ? th : (way + wah) - ny; + resize(c, wax, ny, waw, nh); + ny += nh; + i++; + } +} |