From 8a6152368ac35bb6fc5434add0abe8e6778bbea7 Mon Sep 17 00:00:00 2001 From: Ivan Kanakarakis Date: Sun, 4 Mar 2012 05:06:42 +0200 Subject: [PATCH] resize stack with shortcuts --- config.def.h | 2 ++ monsterwm.c | 57 ++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/config.def.h b/config.def.h index bdc0035f..b5b0b02a 100644 --- a/config.def.h +++ b/config.def.h @@ -62,6 +62,8 @@ static Key keys[] = { { MOD1, XK_k, prev_win, {NULL}}, { MOD1, XK_h, resize_master, {.i = -10}}, /* decrease size in px */ { MOD1, XK_l, resize_master, {.i = +10}}, /* increase size in px */ + { MOD1, XK_o, resize_stack, {.i = -10}}, /* shrink size in px */ + { MOD1, XK_p, resize_stack, {.i = +10}}, /* grow size in px */ { MOD1|CONTROL, XK_h, rotate, {.i = -1}}, { MOD1|CONTROL, XK_l, rotate, {.i = +1}}, { MOD1|SHIFT, XK_h, rotate_filled, {.i = -1}}, diff --git a/monsterwm.c b/monsterwm.c index a6ae2911..3cbe933a 100644 --- a/monsterwm.c +++ b/monsterwm.c @@ -90,6 +90,7 @@ static void next_win(); static void prev_win(); static void quit(const Arg *arg); static void resize_master(const Arg *arg); +static void resize_stack(const Arg *arg); static void rotate(const Arg *arg); static void rotate_filled(const Arg *arg); static void spawn(const Arg *arg); @@ -123,6 +124,7 @@ typedef struct Client { * properties of each desktop * * masz - the size of the master area + * sasz - additional size of the first stack window area * mode - the desktop's tiling layout mode * head - the start of the client list * curr - the currently highlighted window @@ -130,7 +132,7 @@ typedef struct Client { * sbar - the visibility status of the panel/statusbar */ typedef struct { - int mode, masz; + int mode, masz, sasz; Client *head, *curr, *prev; Bool sbar; } Desktop; @@ -953,6 +955,14 @@ void resize_master(const Arg *arg) { else d->masz -= arg->i; /* reset master area size */ } +/** + * resize the first stack window + */ +void resize_stack(const Arg *arg) { + desktops[currdeskidx].sasz += arg->i; + tile(&desktops[currdeskidx]); +} + /** * jump and focus the next or previous desktop */ @@ -1081,26 +1091,51 @@ void stack(int x, int y, int w, int h, const Desktop *d) { /* count stack windows and grab first non-floating, non-fullscreen window */ for (t = d->head; t; t = t->next) if (!ISFFT(t)) { if (c) ++n; else c = t; } - /* if there is only one window, it should cover the available screen space - * if there is only one stack window (n == 1) then we don't care about growth - * if more than one stack windows (n > 1) on screen then adjustments may be needed - * - p is the num of pixels than remain when spliting - * the available width/height to the number of windows - * - z is the clients' height/width + /* if there is only one window (c && !n), it should cover the available screen space + * if there is only one stack window, then we don't care about growth + * if more than one stack windows (n > 1) adjustments may be needed. + * + * - p is the num of pixels than remain when spliting the + * available width/height to the number of windows + * - z is each client's height/width + * + * ---------- --. ----------------------. + * | |----| }--|--> sasz }--> first client will have + * | | 1s | | | z+p+sasz height/width. + * | M |----|-. }--> screen height (h) ---' + * | | 2s | }--|--> client height (z) two stack clients on tile mode + * -----------' -' ::: ascii art by c00kiemon5ter + * + * what we do is, remove the sasz from the screen height/width and then + * divide that space with the windows on the stack so all windows have + * equal height/width: z = (z - sasz)/n + * + * sasz was left out (subtrackted), to later be added to the first client + * height/width. before we do that, there will be cases when the num of + * windows cannot be perfectly divided with the available screen height/width. + * for example: 100px scr. height, and 3 stack windows: 100/3 = 33,3333.. + * so we get that remaining space and merge it to sasz: p = (z - sasz) % n + sasz + * + * in the end, we know each client's height/width (z), and how many pixels + * should be added to the first stack client (p) so that it satisfies sasz, + * and also, does not result in gaps created on the bottom of the screen. */ if (c && !n) XMoveResizeWindow(dis, c->win, x, y, w - 2*BORDER_WIDTH, h - 2*BORDER_WIDTH); - if (!c || !n) return; else if (n > 1) { p = z%n; z /= n; } + if (!c || !n) return; else if (n > 1) { p = (z - d->sasz)%n + d->sasz; z = (z - d->sasz)/n; } /* tile the first non-floating, non-fullscreen window to cover the master area */ if (b) XMoveResizeWindow(dis, c->win, x, y, w - 2*BORDER_WIDTH, ma - BORDER_WIDTH); else XMoveResizeWindow(dis, c->win, x, y, ma - BORDER_WIDTH, h - 2*BORDER_WIDTH); + /* tile the next non-floating, non-fullscreen (and first) stack window adding p */ + for (c = c->next; c && ISFFT(c); c = c->next); int cw = (b ? h:w) - 2*BORDER_WIDTH - ma, ch = z - BORDER_WIDTH; + if (b) XMoveResizeWindow(dis, c->win, x, y += ma, ch - BORDER_WIDTH + p, cw); + else XMoveResizeWindow(dis, c->win, x += ma, y, cw, ch - BORDER_WIDTH + p); - for (x += b ? 0:ma, y += b ? ma:0, c = c->next; c; c = c->next) { + /* tile the rest of the non-floating, non-fullscreen stack windows */ + for (b ? (x += ch+p):(y += ch+p), c = c->next; c; c = c->next) { if (ISFFT(c)) continue; - for (t = c->next; t && ISFFT(t); t = t->next); - if (!t) ch += p - BORDER_WIDTH; /* add remaining space to last window */ if (b) { XMoveResizeWindow(dis, c->win, x, y, ch, cw); x += z; } else { XMoveResizeWindow(dis, c->win, x, y, cw, ch); y += z; } }