diff --git a/README.md b/README.md index 726acd6..15153b3 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t ### Changelog: +2019-09-08 - Added cfacts and vanitygaps patches, added bstack and bstackhoriz layouts + 2019-09-07 - Added cyclelayouts, resizecorners, rotatestack, savefloats, statuspadding, switchtag, center and windowrolerule patches 2019-09-06 - Added attachabove, attachaside, attachbelow, attachbottom, autostart, fancybar, focusonnetactive and losefullscreen patches @@ -40,6 +42,9 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t - [center](https://dwm.suckless.org/patches/center/) - adds an iscentered rule to automatically center clients on the current monitor + - [cfacts](https://dwm.suckless.org/patches/cfacts/) + - the cfacts patch provides the ability to assign different weights to clients in their respective stack in tiled layout + - [cyclelayouts](https://dwm.suckless.org/patches/cyclelayouts/) - lets you cycle through all your layouts @@ -90,9 +95,20 @@ Refer to [https://dwm.suckless.org/](https://dwm.suckless.org/) for details on t - [togglefullscreen](https://github.com/bakkeby/dwm-vanitygaps/blob/master/patches/dwm-togglefullscreen-6.2.diff) - allows you to toggle fullscreen on and off using a single shortcut key + - [vanitygaps](https://github.com/bakkeby/dwm-vanitygaps/blob/master/patches/dwm-vanitygaps-6.2.diff) + - adds configurable gaps between windows differentiating between outer, inner, horizontal and vertical gaps + - [windowrolerule](https://github.com/bakkeby/dwm-vanitygaps/blob/master/patches/dwm-windowrolerule-6.2.diff) - sometimes a single application opens different windows depending on the task at hand and this is often reflected in the WM_WINDOW_ROLE(STRING) x property - this patch adds the role field to the rule configuration so that one can differentiate between, say, Firefox "browser" vs "Preferences" vs "Manager" or Google-chrome "browser" vs "pop-up". - [zoomswap](https://dwm.suckless.org/patches/zoomswap/) - allows a master and a stack window to swap places rather than every window on the screen changing position + +### Layouts included: + + - [bstack](https://dwm.suckless.org/patches/bottomstack/) + - bottomstack layout + + - [bstackhoriz](https://dwm.suckless.org/patches/bottomstack/) + - bottomstack horizontal layout \ No newline at end of file diff --git a/config.def.h b/config.def.h index 36bc4ec..83875cd 100644 --- a/config.def.h +++ b/config.def.h @@ -3,6 +3,13 @@ /* appearance */ static const unsigned int borderpx = 1; /* border pixel of windows */ static const unsigned int snap = 32; /* snap pixel */ +#if VANITYGAPS_PATCH +static const unsigned int gappih = 20; /* horiz inner gap between windows */ +static const unsigned int gappiv = 10; /* vert inner gap between windows */ +static const unsigned int gappoh = 10; /* horiz outer gap between windows and screen edge */ +static const unsigned int gappov = 30; /* vert outer gap between windows and screen edge */ +static int smartgaps = 0; /* 1 means no outer gap when there is only one window */ +#endif // VANITYGAPS_PATCH static const int showbar = 1; /* 0 means no bar */ static const int topbar = 1; /* 0 means bottom bar */ #if STATUSPADDING_PATCH @@ -88,9 +95,19 @@ static const int resizehints = 1; /* 1 means respect size hints in tiled resi static const Layout layouts[] = { /* symbol arrange function */ + #if TILE_LAYOUT { "[]=", tile }, /* first entry is default */ + #endif // TILE_LAYOUT { "><>", NULL }, /* no layout function means floating behavior */ + #if MONOCLE_LAYOUT { "[M]", monocle }, + #endif // MONOCLE_LAYOUT + #if BSTACK_LAYOUT + { "TTT", bstack }, + #endif // BSTACK_LAYOUT + #if BSTACKHORIZ_LAYOUT + { "===", bstackhoriz }, + #endif // BSTACKHORIZ_LAYOUT #if CYCLELAYOUTS_PATCH { NULL, NULL }, #endif // CYCLELAYOUTS_PATCH @@ -127,7 +144,30 @@ static Key keys[] = { { MODKEY, XK_d, incnmaster, {.i = -1 } }, { MODKEY, XK_h, setmfact, {.f = -0.05} }, { MODKEY, XK_l, setmfact, {.f = +0.05} }, + #if CFACTS_PATCH + { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} }, + { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} }, + { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} }, + #endif // CFACTS_PATCH { MODKEY, XK_Return, zoom, {0} }, + #if VANITYGAPS_PATCH + { MODKEY|Mod4Mask, XK_u, incrgaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_u, incrgaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_i, incrigaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_i, incrigaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_o, incrogaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_o, incrogaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_6, incrihgaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_6, incrihgaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_7, incrivgaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_7, incrivgaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_8, incrohgaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_8, incrohgaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_9, incrovgaps, {.i = +1 } }, + { MODKEY|Mod4Mask|ShiftMask, XK_9, incrovgaps, {.i = -1 } }, + { MODKEY|Mod4Mask, XK_0, togglegaps, {0} }, + { MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} }, + #endif // VANITYGAPS_PATCH { MODKEY, XK_Tab, view, {0} }, { MODKEY|ShiftMask, XK_c, killclient, {0} }, { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, diff --git a/dwm.c b/dwm.c index 92bb52a..b2dbb37 100644 --- a/dwm.c +++ b/dwm.c @@ -103,6 +103,9 @@ typedef struct Client Client; struct Client { char name[256]; float mina, maxa; + #if CFACTS_PATCH + float cfact; + #endif // CFACTS_PATCH int x, y, w, h; #if SAVEFLOATS_PATCH int sfx, sfy, sfw, sfh; /* stored float geometry, used on mode revert */ @@ -144,6 +147,12 @@ struct Monitor { int by; /* bar geometry */ int mx, my, mw, mh; /* screen size */ int wx, wy, ww, wh; /* window area */ + #if VANITYGAPS_PATCH + int gappih; /* horizontal gap between windows */ + int gappiv; /* vertical gap between windows */ + int gappoh; /* horizontal outer gaps */ + int gappov; /* vertical outer gaps */ + #endif // VANITYGAPS_PATCH unsigned int seltags; unsigned int sellt; unsigned int tagset[2]; @@ -217,7 +226,6 @@ static void killclient(const Arg *arg); static void manage(Window w, XWindowAttributes *wa); static void mappingnotify(XEvent *e); static void maprequest(XEvent *e); -static void monocle(Monitor *m); static void motionnotify(XEvent *e); static void movemouse(const Arg *arg); static Client *nexttiled(Client *c); @@ -251,7 +259,6 @@ static void sigchld(int unused); static void spawn(const Arg *arg); static void tag(const Arg *arg); static void tagmon(const Arg *arg); -static void tile(Monitor *); static void togglebar(const Arg *arg); static void togglefloating(const Arg *arg); static void toggletag(const Arg *arg); @@ -796,6 +803,12 @@ createmon(void) m->nmaster = nmaster; m->showbar = showbar; m->topbar = topbar; + #if VANITYGAPS_PATCH + m->gappih = gappih; + m->gappiv = gappiv; + m->gappoh = gappoh; + m->gappov = gappov; + #endif // VANITYGAPS_PATCH m->lt[0] = &layouts[0]; m->lt[1] = &layouts[1 % LENGTH(layouts)]; strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); @@ -1340,6 +1353,9 @@ manage(Window w, XWindowAttributes *wa) c->w = c->oldw = wa->width; c->h = c->oldh = wa->height; c->oldbw = wa->border_width; + #if CFACTS_PATCH + c->cfact = 1.0; + #endif // CFACTS_PATCH updatetitle(c); if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { @@ -1436,21 +1452,6 @@ maprequest(XEvent *e) manage(ev->window, &wa); } -void -monocle(Monitor *m) -{ - unsigned int n = 0; - Client *c; - - for (c = m->clients; c; c = c->next) - if (ISVISIBLE(c)) - n++; - if (n > 0) /* override layout symbol */ - snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); - for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) - resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); -} - void motionnotify(XEvent *e) { @@ -2189,32 +2190,6 @@ tagmon(const Arg *arg) #endif // TAGMONFIXFS_PATCH } -void -tile(Monitor *m) -{ - unsigned int i, n, h, mw, my, ty; - Client *c; - - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - if (n == 0) - return; - - if (n > m->nmaster) - mw = m->nmaster ? m->ww * m->mfact : 0; - else - mw = m->ww; - for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) - if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i); - resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); - my += HEIGHT(c); - } else { - h = (m->wh - ty) / (n - i); - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); - ty += HEIGHT(c); - } -} - void togglebar(const Arg *arg) { diff --git a/patch/bstack.c b/patch/bstack.c new file mode 100644 index 0000000..d202e06 --- /dev/null +++ b/patch/bstack.c @@ -0,0 +1,152 @@ +#if VANITYGAPS_PATCH && CFACTS_PATCH +static void +bstack(Monitor *m) +{ + unsigned int i, n; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + int oh, ov, ih, iv; + float mfacts, sfacts; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n, &mfacts, &sfacts); + + if (n == 0) + return; + + sx = mx = m->wx + ov; + sy = my = m->wy + oh; + sh = mh = m->wh - 2*oh; + sw = mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); + + if (m->nmaster && n > m->nmaster) { + sh = (mh - ih) * (1 - m->mfact); + mh = (mh - ih) * m->mfact; + sx = mx; + sy = my + mh + ih; + sw = m->ww - 2*ov - iv * (n - m->nmaster - 1); + } + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i < m->nmaster) { + resize(c, mx, my, mw * (c->cfact / mfacts) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c) + iv; + } else { + resize(c, sx, sy, sw * (c->cfact / sfacts) - (2*c->bw), sh - (2*c->bw), 0); + sx += WIDTH(c) + iv; + } + } +} +#elif VANITYGAPS_PATCH +static void +bstack(Monitor *m) +{ + unsigned int i, n; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + int oh, ov, ih, iv; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n); + + if (n == 0) + return; + + sx = mx = m->wx + ov; + sy = my = m->wy + oh; + sh = mh = m->wh - 2*oh; + sw = mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); + + if (m->nmaster && n > m->nmaster) { + sh = (mh - ih) * (1 - m->mfact); + mh = (mh - ih) * m->mfact; + sy = my + mh + ih; + sw = m->ww - 2*ov - iv * (n - m->nmaster - 1); + } + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i < m->nmaster) { + resize(c, mx, my, mw / MIN(n, m->nmaster) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c) + iv; + } else { + resize(c, sx, sy, sw / (n - MIN(n, m->nmaster)) - (2*c->bw), sh - (2*c->bw), 0); + sx += WIDTH(c) + iv; + } + } +} +#elif CFACTS_PATCH +static void +bstack(Monitor *m) +{ + unsigned int i, n; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + float mfacts = 1, sfacts = 1; + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) { + if (n < m->nmaster) + mfacts += c->cfact; + else + sfacts += c->cfact; + } + + if (n == 0) + return; + + sx = mx = m->wx; + sy = my = m->wy; + sh = mh = m->wh; + sw = mw = m->ww; + + if (m->nmaster && n > m->nmaster) { + sh = mh * (1 - m->mfact); + mh = mh * m->mfact; + sy = my + mh; + } + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i < m->nmaster) { + resize(c, mx, my, mw * (c->cfact / mfacts) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c); + } else { + resize(c, sx, sy, sw * (c->cfact / sfacts) - (2*c->bw), sh - (2*c->bw), 0); + sx += WIDTH(c); + } + } +} +#else +static void +bstack(Monitor *m) +{ + unsigned int i, n; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + if (n == 0) + return; + + sx = mx = m->wx; + sy = my = m->wy; + sh = mh = m->wh; + sw = mw = m->ww; + + if (m->nmaster && n > m->nmaster) { + sh = mh * (1 - m->mfact); + mh = mh * m->mfact; + sy = my + mh; + } + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i < m->nmaster) { + resize(c, mx, my, mw / MIN(n, m->nmaster) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c); + } else { + resize(c, sx, sy, sw / (n - MIN(n, m->nmaster)) - (2*c->bw), sh - (2*c->bw), 0); + sx += WIDTH(c); + } + } +} +#endif \ No newline at end of file diff --git a/patch/bstack.h b/patch/bstack.h new file mode 100644 index 0000000..56c99ff --- /dev/null +++ b/patch/bstack.h @@ -0,0 +1 @@ +static void bstack(Monitor *m); \ No newline at end of file diff --git a/patch/bstackhoriz.c b/patch/bstackhoriz.c new file mode 100644 index 0000000..3a4d11a --- /dev/null +++ b/patch/bstackhoriz.c @@ -0,0 +1,155 @@ +#if VANITYGAPS_PATCH && CFACTS_PATCH +static void +bstackhoriz(Monitor *m) +{ + unsigned int i, n; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + int oh, ov, ih, iv; + float mfacts, sfacts; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n, &mfacts, &sfacts); + + if (n == 0) + return; + + sx = mx = m->wx + ov; + sy = my = m->wy + oh; + sh = mh = m->wh - 2*oh; + sw = mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); + + if (m->nmaster && n > m->nmaster) { + sh = (mh - ih) * (1 - m->mfact); + mh = (mh - ih) * m->mfact; + sy = my + mh + ih; + sh = m->wh - mh - 2*oh - ih * (n - m->nmaster); + sw = m->ww - 2*ov; + } + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i < m->nmaster) { + resize(c, mx, my, mw * (c->cfact / mfacts) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c) + iv; + } else { + resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) - (2*c->bw), 0); + sy += HEIGHT(c) + ih; + } + } +} +#elif VANITYGAPS_PATCH +static void +bstackhoriz(Monitor *m) +{ + unsigned int i, n; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + int oh, ov, ih, iv; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n); + + if (n == 0) + return; + + sx = mx = m->wx + ov; + sy = my = m->wy + oh; + sh = mh = m->wh - 2*oh; + sw = mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1); + + if (m->nmaster && n > m->nmaster) { + sh = (mh - ih) * (1 - m->mfact); + mh = (mh - ih) * m->mfact; + sy = my + mh + ih; + sh = m->wh - mh - 2*oh - ih * (n - m->nmaster); + sw = m->ww - 2*ov; + } + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i < m->nmaster) { + resize(c, mx, my, mw / MIN(n, m->nmaster) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c) + iv; + } else { + resize(c, sx, sy, sw - (2*c->bw), sh / (n - MIN(n, m->nmaster)) - (2*c->bw), 0); + sy += HEIGHT(c) + ih; + } + } +} +#elif CFACTS_PATCH +static void +bstackhoriz(Monitor *m) +{ + unsigned int i, n; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + float mfacts = 1, sfacts = 1; + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) { + if (n < m->nmaster) + mfacts += c->cfact; + else + sfacts += c->cfact; + } + + if (n == 0) + return; + + sx = mx = m->wx; + sy = my = m->wy; + sh = mh = m->wh; + sw = mw = m->ww; + + if (m->nmaster && n > m->nmaster) { + sh = mh * (1 - m->mfact); + mh = mh * m->mfact; + sy = my + mh; + sh = m->wh - mh; + } + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i < m->nmaster) { + resize(c, mx, my, mw * (c->cfact / mfacts) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c); + } else { + resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) - (2*c->bw), 0); + sy += HEIGHT(c); + } + } +} +#else +static void +bstackhoriz(Monitor *m) +{ + unsigned int i, n; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + if (n == 0) + return; + + sx = mx = m->wx; + sy = my = m->wy; + sh = mh = m->wh; + sw = mw = m->ww; + + if (m->nmaster && n > m->nmaster) { + sh = mh * (1 - m->mfact); + mh = mh * m->mfact; + sy = my + mh; + sh = m->wh - mh; + } + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) { + if (i < m->nmaster) { + resize(c, mx, my, mw / MIN(n, m->nmaster) - (2*c->bw), mh - (2*c->bw), 0); + mx += WIDTH(c); + } else { + resize(c, sx, sy, sw - (2*c->bw), sh / (n - MIN(n, m->nmaster)) - (2*c->bw), 0); + sy += HEIGHT(c); + } + } +} +#endif \ No newline at end of file diff --git a/patch/bstackhoriz.h b/patch/bstackhoriz.h new file mode 100644 index 0000000..8dd0ebd --- /dev/null +++ b/patch/bstackhoriz.h @@ -0,0 +1 @@ +static void bstackhoriz(Monitor *m); \ No newline at end of file diff --git a/patch/cfacts.c b/patch/cfacts.c new file mode 100644 index 0000000..085071f --- /dev/null +++ b/patch/cfacts.c @@ -0,0 +1,17 @@ +void +setcfact(const Arg *arg) { + float f; + Client *c; + + c = selmon->sel; + + if (!arg || !c || !selmon->lt[selmon->sellt]->arrange) + return; + f = arg->f + c->cfact; + if (arg->f == 0.0) + f = 1.0; + else if (f < 0.25 || f > 4.0) + return; + c->cfact = f; + arrange(selmon); +} \ No newline at end of file diff --git a/patch/cfacts.h b/patch/cfacts.h new file mode 100644 index 0000000..b8d8b04 --- /dev/null +++ b/patch/cfacts.h @@ -0,0 +1 @@ +static void setcfact(const Arg *arg); \ No newline at end of file diff --git a/patch/include.c b/patch/include.c index b5cf100..b333fbc 100644 --- a/patch/include.c +++ b/patch/include.c @@ -1,3 +1,5 @@ +/* Patches */ + #if ALPHA_PATCH #include "alpha.c" #endif @@ -10,9 +12,13 @@ #include "autostart.c" #endif +#if CFACTS_PATCH +#include "cfacts.c" +#endif + #if CYCLELAYOUTS_PATCH #include "cyclelayouts.c" -#endif // CYCLELAYOUTS_PATCH +#endif #if PERTAG_PATCH #include "pertag.c" @@ -38,6 +44,28 @@ #include "togglefullscreen.c" #endif +#if VANITYGAPS_PATCH +#include "vanitygaps.c" +#endif + #if ZOOMSWAP_PATCH #include "zoomswap.c" #endif + +/* Layouts */ + +#if BSTACK_LAYOUT +#include "bstack.c" +#endif + +#if BSTACKHORIZ_LAYOUT +#include "bstackhoriz.c" +#endif + +#if MONOCLE_LAYOUT +#include "monocle.c" +#endif + +#if TILE_LAYOUT +#include "tile.c" +#endif \ No newline at end of file diff --git a/patch/include.h b/patch/include.h index e324b55..bd68e54 100644 --- a/patch/include.h +++ b/patch/include.h @@ -1,3 +1,5 @@ +/* Patches */ + #if ALPHA_PATCH #include "alpha.h" #endif @@ -10,6 +12,10 @@ #include "autostart.h" #endif +#if CFACTS_PATCH +#include "cfacts.h" +#endif + #if CYCLELAYOUTS_PATCH #include "cyclelayouts.h" #endif @@ -34,6 +40,28 @@ #include "togglefullscreen.h" #endif +#if VANITYGAPS_PATCH +#include "vanitygaps.h" +#endif + #if ZOOMSWAP_PATCH #include "zoomswap.h" +#endif + +/* Layouts */ + +#if BSTACK_LAYOUT +#include "bstack.h" +#endif + +#if BSTACKHORIZ_LAYOUT +#include "bstackhoriz.h" +#endif + +#if MONOCLE_LAYOUT +#include "monocle.h" +#endif + +#if TILE_LAYOUT +#include "tile.h" #endif \ No newline at end of file diff --git a/patch/monocle.c b/patch/monocle.c new file mode 100644 index 0000000..5d7a270 --- /dev/null +++ b/patch/monocle.c @@ -0,0 +1,14 @@ +void +monocle(Monitor *m) +{ + unsigned int n = 0; + Client *c; + + for (c = m->clients; c; c = c->next) + if (ISVISIBLE(c)) + n++; + if (n > 0) /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); + for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) + resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); +} \ No newline at end of file diff --git a/patch/monocle.h b/patch/monocle.h new file mode 100644 index 0000000..d3df960 --- /dev/null +++ b/patch/monocle.h @@ -0,0 +1 @@ +static void monocle(Monitor *m); \ No newline at end of file diff --git a/patch/tile.c b/patch/tile.c new file mode 100644 index 0000000..866a684 --- /dev/null +++ b/patch/tile.c @@ -0,0 +1,140 @@ +#if VANITYGAPS_PATCH && CFACTS_PATCH +static void +tile(Monitor *m) +{ + unsigned int i, n; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + int oh, ov, ih, iv; + float mfacts, sfacts; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n, &mfacts, &sfacts); + + if (n == 0) + return; + + sx = mx = m->wx + ov; + sy = my = m->wy + oh; + sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); + sw = mw = m->ww - 2*ov; + + if (m->nmaster && n > m->nmaster) { + sw = (mw - iv) * (1 - m->mfact); + mw = (mw - iv) * m->mfact; + sx = mx + mw + iv; + sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); + } + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { + resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) - (2*c->bw), 0); + my += HEIGHT(c) + ih; + } else { + resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) - (2*c->bw), 0); + sy += HEIGHT(c) + ih; + } +} +#elif VANITYGAPS_PATCH +static void +tile(Monitor *m) +{ + unsigned int i, n; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + int oh, ov, ih, iv; + Client *c; + + getgaps(m, &oh, &ov, &ih, &iv, &n); + + if (n == 0) + return; + + sx = mx = m->wx + ov; + sy = my = m->wy + oh; + sh = mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1); + sw = mw = m->ww - 2*ov; + + if (m->nmaster && n > m->nmaster) { + sw = (mw - iv) * (1 - m->mfact); + mw = (mw - iv) * m->mfact; + sx = mx + mw + iv; + sh = m->wh - 2*oh - ih * (n - m->nmaster - 1); + } + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { + resize(c, mx, my, mw - (2*c->bw), mh / MIN(n, m->nmaster) - (2*c->bw), 0); + my += HEIGHT(c) + ih; + } else { + resize(c, sx, sy, sw - (2*c->bw), sh / (n - MIN(n, m->nmaster)) - (2*c->bw), 0); + sy += HEIGHT(c) + ih; + } +} +#elif CFACTS_PATCH +static void +tile(Monitor *m) +{ + unsigned int i, n; + int mx = 0, my = 0, mh = 0, mw = 0; + int sx = 0, sy = 0, sh = 0, sw = 0; + float mfacts = 1, sfacts = 1; + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) { + if (n < m->nmaster) + mfacts += c->cfact; + else + sfacts += c->cfact; + } + + if (n == 0) + return; + + sx = mx = m->wx; + sy = my = m->wy; + sh = mh = m->wh; + sw = mw = m->ww; + + if (m->nmaster && n > m->nmaster) { + sw = mw * (1 - m->mfact); + mw = mw * m->mfact; + sx = mx + mw; + } + + for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { + resize(c, mx, my, mw - (2*c->bw), mh * (c->cfact / mfacts) - (2*c->bw), 0); + my += HEIGHT(c); + } else { + resize(c, sx, sy, sw - (2*c->bw), sh * (c->cfact / sfacts) - (2*c->bw), 0); + sy += HEIGHT(c); + } +} +#else +void +tile(Monitor *m) +{ + unsigned int i, n, h, mw, my, ty; + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + if (n == 0) + return; + + if (n > m->nmaster) + mw = m->nmaster ? m->ww * m->mfact : 0; + else + mw = m->ww; + for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { + h = (m->wh - my) / (MIN(n, m->nmaster) - i); + resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); + my += HEIGHT(c); + } else { + h = (m->wh - ty) / (n - i); + resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); + ty += HEIGHT(c); + } +} +#endif \ No newline at end of file diff --git a/patch/tile.h b/patch/tile.h new file mode 100644 index 0000000..8730e13 --- /dev/null +++ b/patch/tile.h @@ -0,0 +1 @@ +static void tile(Monitor *); \ No newline at end of file diff --git a/patch/vanitygaps.c b/patch/vanitygaps.c new file mode 100644 index 0000000..b8c1557 --- /dev/null +++ b/patch/vanitygaps.c @@ -0,0 +1,143 @@ +/* Settings */ +static int enablegaps = 1; + +static void +setgaps(int oh, int ov, int ih, int iv) +{ + if (oh < 0) oh = 0; + if (ov < 0) ov = 0; + if (ih < 0) ih = 0; + if (iv < 0) iv = 0; + + selmon->gappoh = oh; + selmon->gappov = ov; + selmon->gappih = ih; + selmon->gappiv = iv; + arrange(selmon); +} + +static void +togglegaps(const Arg *arg) +{ + enablegaps = !enablegaps; + arrange(NULL); +} + +static void +defaultgaps(const Arg *arg) +{ + setgaps(gappoh, gappov, gappih, gappiv); +} + +static void +incrgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh + arg->i, + selmon->gappov + arg->i, + selmon->gappih + arg->i, + selmon->gappiv + arg->i + ); +} + +static void +incrigaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov, + selmon->gappih + arg->i, + selmon->gappiv + arg->i + ); +} + +static void +incrogaps(const Arg *arg) +{ + setgaps( + selmon->gappoh + arg->i, + selmon->gappov + arg->i, + selmon->gappih, + selmon->gappiv + ); +} + +static void +incrohgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh + arg->i, + selmon->gappov, + selmon->gappih, + selmon->gappiv + ); +} + +static void +incrovgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov + arg->i, + selmon->gappih, + selmon->gappiv + ); +} + +static void +incrihgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov, + selmon->gappih + arg->i, + selmon->gappiv + ); +} + +static void +incrivgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov, + selmon->gappih, + selmon->gappiv + arg->i + ); +} + +static void +#if CFACTS_PATCH +getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc, float *mf, float *sf) +#else +getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc ) +#endif // CFACTS_PATCH +{ + unsigned int n, oe = enablegaps, ie = enablegaps; + #if CFACTS_PATCH + float mfacts = 0, sfacts = 0; + #endif // CFACTS_PATCH + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) { + #if CFACTS_PATCH + if (!m->nmaster || n < m->nmaster) + mfacts += c->cfact; + else + sfacts += c->cfact; + #endif // CFACTS_PATCH + } + if (smartgaps && n == 1) { + oe = 0; // outer gaps disabled when only one client + } + + *oh = m->gappoh*oe; // outer horizontal gap + *ov = m->gappov*oe; // outer vertical gap + *ih = m->gappih*ie; // inner horizontal gap + *iv = m->gappiv*ie; // inner vertical gap + *nc = n; // number of clients + #if CFACTS_PATCH + *mf = mfacts; // total factor of master area + *sf = sfacts; // total factor of slave area + #endif // CFACTS_PATCH +} \ No newline at end of file diff --git a/patch/vanitygaps.h b/patch/vanitygaps.h new file mode 100644 index 0000000..bb1df18 --- /dev/null +++ b/patch/vanitygaps.h @@ -0,0 +1,18 @@ +/* Key binding functions */ +static void defaultgaps(const Arg *arg); +static void incrgaps(const Arg *arg); +static void incrigaps(const Arg *arg); +static void incrogaps(const Arg *arg); +static void incrohgaps(const Arg *arg); +static void incrovgaps(const Arg *arg); +static void incrihgaps(const Arg *arg); +static void incrivgaps(const Arg *arg); +static void togglegaps(const Arg *arg); + +/* Internals */ +#if CFACTS_PATCH +static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc, float *mf, float *sf); +#else +static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc); +#endif // CFACTS_PATCH +static void setgaps(int oh, int ov, int ih, int iv); \ No newline at end of file diff --git a/patches.h b/patches.h index 5be6d9b..7cfd50f 100644 --- a/patches.h +++ b/patches.h @@ -5,8 +5,13 @@ * you may want. In cases where patches are logically incompatible * one patch may take precedence over the other as noted in the * relevant descriptions. + * + * Although layouts typically come as patches they are differentiated + * here for grouping purposes. */ +/* Patches */ + /* The alpha patch adds transparency for the status bar. * https://dwm.suckless.org/patches/alpha/ */ @@ -49,6 +54,12 @@ */ #define CENTER_PATCH 0 +/* This patch provides the ability to assign different weights to clients in their + * respective stack in tiled layout. + * https://dwm.suckless.org/patches/cfacts/ + */ +#define CFACTS_PATCH 0 + /* The cyclelayouts patch lets you cycle through all your layouts. * https://dwm.suckless.org/patches/cyclelayouts/ */ @@ -152,6 +163,12 @@ */ #define TOGGLEFULLSCREEN_PATCH 0 +/* This patch adds configurable gaps between windows differentiating between outer, inner, + * horizontal and vertical gaps. + * https://github.com/bakkeby/dwm-vanitygaps/blob/master/patches/dwm-vanitygaps-6.2.diff + * https://github.com/bakkeby/dwm-vanitygaps/blob/master/patches/dwm-vanitygaps-cfacts-6.2.diff + */ +#define VANITYGAPS_PATCH 0 /* Sometimes a single application opens different windows depending on the task * at hand and this is often reflected in the WM_WINDOW_ROLE(STRING) x property. @@ -166,4 +183,26 @@ * rather than every window on the screen changing position. * https://dwm.suckless.org/patches/zoomswap/ */ -#define ZOOMSWAP_PATCH 0 \ No newline at end of file +#define ZOOMSWAP_PATCH 0 + +/* Layouts */ + +/* Bottomstack layout. + * https://dwm.suckless.org/patches/bottomstack/ + */ +#define BSTACK_LAYOUT 0 + +/* Bottomstack horizontal layout. + * https://dwm.suckless.org/patches/bottomstack/ + */ +#define BSTACKHORIZ_LAYOUT 0 + +/* The default tile layout. + * This can be optionally disabled in favour of other layouts. + */ +#define TILE_LAYOUT 1 + +/* Monocle (default) + * This can be optionally disabled in favour of other layouts. + */ +#define MONOCLE_LAYOUT 1 \ No newline at end of file