typedef struct { int x, y, w, h; } Booth; static void apply_lt(Monitor *m, void (*ltf)(Client **, Booth *, unsigned int)); static void apply_mslts(Monitor *m, Bool hsplit, void (*mltf)(Client **, Booth *, unsigned int), /* master layout func */ void (*sltf)(Client **, Booth *, unsigned int)); /* slave layout func */ static void lt_hstack(Client **c, Booth *b, unsigned int n); static void lt_vstack(Client **c, Booth *b, unsigned int n); static void lt_grid(Client **c, Booth *b, unsigned int n); static void lt_monocle(Client **c, Booth *b, unsigned int n); /* Example master-slave layouts */ static void ntile(Monitor *m); static void ncol(Monitor *m); static void bstack(Monitor *m); static void grid(Monitor *m); static void ntile(Monitor *m) { apply_mslts(m, False, lt_vstack, lt_vstack); } static void ncol(Monitor *m) { apply_mslts(m, False, lt_hstack, lt_vstack); } static void bstack(Monitor *m) { apply_mslts(m, True, lt_hstack, lt_hstack); } static void grid(Monitor *m) { apply_mslts(m, False, lt_vstack, lt_grid); } /* Functions that apply layouts */ static void apply_lt(Monitor *m, void (*ltf)(Client **, Booth *, unsigned int)) { unsigned int n; Client *c; for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); if(n == 0) return; c = m->clients; Booth b = { .x = m->wx, .y = m->wy, .w = m->ww, .h = m->wh }; (*ltf)(&c, &b, n); } static void apply_mslts(Monitor *m, Bool hsplit, void (*mltf)(Client **, Booth *, unsigned int), void (*sltf)(Client **, Booth *, unsigned int)) { unsigned int nm, n; Client *c; for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); if(n == 0) return; nm = MIN(n, m->nmaster); /* number of masters */ if (nm == 0) { /* all slaves */ c = m->clients; Booth b = { .x = m->wx, .y = m->wy, .w = m->ww, .h = m->wh }; (*sltf)(&c, &b, n); } else if(n > nm) { /* masters and slaves */ c = m->clients; if(hsplit) { /* masters above slaves */ Booth b = { .x = m->wx, .y = m->wy, .w = m->ww, .h = m->wh * m->mfact }; (*mltf)(&c, &b, nm); b.y += b.h; b.h = m->wh - b.h; (*sltf)(&c, &b, n - nm); } else { /* masters at the left of slaves */ Booth b = { .x = m->wx, .y = m->wy, .w = m->ww * m->mfact, .h = m->wh }; (*mltf)(&c, &b, nm); b.x += b.w; b.w = m->ww - b.w; (*sltf)(&c, &b, n - nm); } } else { /* all masters */ c = m->clients; Booth b = { .x = m->wx, .y = m->wy, .w = m->ww, .h = m->wh }; (*mltf)(&c, &b, n); } } /* Layout functions: the actual algorithms */ static void lt_hstack(Client **c, Booth *b, unsigned int n) { unsigned int i; int x, y, w, h; x = b->x; /* x offset of the next cell */ y = b->y; h = b->h; for(i = 0, *c = nexttiled(*c); *c && i < n; *c = nexttiled((*c)->next), i++) { w = (b->x + b->w - x) / (n - i); resize(*c, x, y, w - 2 * (*c)->bw, h - 2 * (*c)->bw, False); x += WIDTH(*c); } } static void lt_vstack(Client **c, Booth *b, unsigned int n) { unsigned int i; int x, y, w, h; x = b->x; y = b->y; /* y offset of the next cell */ w = b->w; for(i = 0, *c = nexttiled(*c); *c && i < n; *c = nexttiled((*c)->next), i++) { h = (b->y + b->h - y) / (n - i); resize(*c, x, y, w - 2 * (*c)->bw, h - 2 * (*c)->bw, False); y += HEIGHT(*c); } } static void lt_monocle(Client **c, Booth *b, unsigned int n) { unsigned int i; for(i = 0, *c = nexttiled(*c); *c && i < n; *c = nexttiled((*c)->next), i++) resize(*c, b->x, b->y, b->w - 2 * (*c)->bw, b->h - 2 * (*c)->bw, False); } static void lt_grid(Client **c, Booth *b, unsigned int n) { unsigned int cols, rows, cn, rn, i, cx, cy, cw, ch; /* grid dimensions */ for(cols = 0; cols <= n / 2; cols++) if(cols * cols >= n) break; if(n == 5) /* set layout against the general rule: not 1:2:2, but 2:3 */ cols = 2; rows = n / cols; /* window geometries */ cw = cols ? b->w / cols : b->w; cn = 0; /* current column number */ rn = 0; /* current row number */ for(i = 0, *c = nexttiled(*c); *c && i < n; *c = nexttiled((*c)->next), i++) { if(i / rows + 1 > cols - n % cols) rows = n / cols + 1; ch = rows ? b->h / rows : b->h; cx = b->x + cn * cw; cy = b->y + rn * ch; resize(*c, cx, cy, cw - 2 * (*c)->bw, ch - 2 * (*c)->bw, False); rn++; if(rn >= rows) { rn = 0; cn++; } } }