#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++; } }