From bd93ca3aae2a1b3e6ce5eef42f4bdccc4edc512c Mon Sep 17 00:00:00 2001 From: speedie Date: Tue, 4 Jul 2023 18:05:12 +0200 Subject: [PATCH] add vanitygaps --- config.h | 117 ++++++++++++++++++++++++---------------- dwm.c | 31 +++++++++++ libs/gaps.c | 143 +++++++++++++++++++++++++++++++++++++++++++++++++ libs/gaps.h | 12 +++++ libs/lt/tile.c | 11 +--- 5 files changed, 260 insertions(+), 54 deletions(-) create mode 100644 libs/gaps.c create mode 100644 libs/gaps.h diff --git a/config.h b/config.h index c782fb7..f0983e7 100644 --- a/config.h +++ b/config.h @@ -3,6 +3,11 @@ /* appearance */ static const unsigned int borderpx = 1; /* border pixel of windows */ static const unsigned int snap = 32; /* snap pixel */ +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 */ static const int showbar = 1; /* 0 means no bar */ static const int topbar = 1; /* 0 means bottom bar */ static const unsigned int systrayspacing = 2; /* systray spacing */ @@ -15,6 +20,8 @@ static char col_gray3[] = "#bbbbbb"; static char col_gray4[] = "#eeeeee"; static char col_cyan[] = "#005577"; +static const int monoclenogaps = 1; + /* tagging */ static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; @@ -89,54 +96,74 @@ static const Layout layouts[] = { /* commands */ static const char *spmenucmd[] = { "spmenu_run", "-x", NULL }; +static const char *spmenucmd_d[] = { "spmenu_run", "-d", NULL }; static const char *termcmd[] = { "st", NULL }; static const Key keys[] = { - /* modifier key function argument */ - { MODKEY, XK_p, spawn, {.v = spmenucmd } }, - { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, - { MODKEY, XK_b, togglebar, {0} }, - { MODKEY, XK_j, focusstack, {.i = +1 } }, - { MODKEY, XK_k, focusstack, {.i = -1 } }, - { MODKEY, XK_i, incnmaster, {.i = +1 } }, - { MODKEY, XK_d, incnmaster, {.i = -1 } }, - { MODKEY|ControlMask, XK_i, incnstack, {.i = +1 } }, - { MODKEY|ControlMask, XK_u, incnstack, {.i = -1 } }, - { MODKEY, XK_h, setmfact, {.f = -0.05} }, - { MODKEY, XK_l, setmfact, {.f = +0.05} }, - { MODKEY, XK_Return, zoom, {0} }, - { MODKEY, XK_Tab, view, {0} }, - { MODKEY|ControlMask, XK_z, showhideclient, {0} }, - { MODKEY|ShiftMask, XK_q, killclient, {0} }, - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, - { MODKEY|ControlMask, XK_w, rotatelayoutaxis, {.i = +1 } }, /* flextile, 1 = layout axis */ - { MODKEY|ControlMask, XK_e, rotatelayoutaxis, {.i = +2 } }, /* flextile, 2 = master axis */ - { MODKEY|ControlMask, XK_r, rotatelayoutaxis, {.i = +3 } }, /* flextile, 3 = stack axis */ - { MODKEY|ControlMask, XK_t, rotatelayoutaxis, {.i = +4 } }, /* flextile, 4 = secondary stack axis */ - { MODKEY|ControlMask|ShiftMask, XK_w, rotatelayoutaxis, {.i = -1 } }, /* flextile, 1 = layout axis */ - { MODKEY|ControlMask|ShiftMask, XK_e, rotatelayoutaxis, {.i = -2 } }, /* flextile, 2 = master axis */ - { MODKEY|ControlMask|ShiftMask, XK_r, rotatelayoutaxis, {.i = -3 } }, /* flextile, 3 = stack axis */ - { MODKEY|ControlMask|ShiftMask, XK_t, rotatelayoutaxis, {.i = -4 } }, /* flextile, 4 = secondary stack axis */ - { MODKEY|ControlMask, XK_Return, mirrorlayout, {0} }, /* flextile, flip master and stack areas */ - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, - { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, - { MODKEY, XK_comma, focusmon, {.i = -1 } }, - { MODKEY, XK_period, focusmon, {.i = +1 } }, - { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, - { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, - TAGKEYS( XK_1, 0) - TAGKEYS( XK_2, 1) - TAGKEYS( XK_3, 2) - TAGKEYS( XK_4, 3) - TAGKEYS( XK_5, 4) - TAGKEYS( XK_6, 5) - TAGKEYS( XK_7, 6) - TAGKEYS( XK_8, 7) - TAGKEYS( XK_9, 8) + /* modifier key function argument */ + { MODKEY, XK_semicolon, spawn, {.v = spmenucmd_d } }, + { MODKEY|ShiftMask, XK_semicolon, spawn, {.v = spmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY|ControlMask, XK_i, incnstack, {.i = +1 } }, + { MODKEY|ControlMask, XK_u, incnstack, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY|ShiftMask, XK_h, setcfact, {.f = +0.25} }, + { MODKEY|ShiftMask, XK_l, setcfact, {.f = -0.25} }, + { MODKEY|ShiftMask, XK_o, setcfact, {.f = 0.00} }, + { 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|ShiftMask, XK_0, defaultgaps, {0} }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ControlMask, XK_z, showhideclient, {0} }, + { MODKEY|ShiftMask, XK_q, killclient, {0} }, + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY|ControlMask, XK_w, rotatelayoutaxis, {.i = +1 } }, /* flextile, 1 = layout axis */ + { MODKEY|ControlMask, XK_e, rotatelayoutaxis, {.i = +2 } }, /* flextile, 2 = master axis */ + { MODKEY|ControlMask, XK_r, rotatelayoutaxis, {.i = +3 } }, /* flextile, 3 = stack axis */ + { MODKEY|ControlMask, XK_t, rotatelayoutaxis, {.i = +4 } }, /* flextile, 4 = secondary stack axis */ + { MODKEY|ControlMask|ShiftMask, XK_w, rotatelayoutaxis, {.i = -1 } }, /* flextile, 1 = layout axis */ + { MODKEY|ControlMask|ShiftMask, XK_e, rotatelayoutaxis, {.i = -2 } }, /* flextile, 2 = master axis */ + { MODKEY|ControlMask|ShiftMask, XK_r, rotatelayoutaxis, {.i = -3 } }, /* flextile, 3 = stack axis */ + { MODKEY|ControlMask|ShiftMask, XK_t, rotatelayoutaxis, {.i = -4 } }, /* flextile, 4 = secondary stack axis */ + { MODKEY|ControlMask, XK_Return, mirrorlayout, {0} }, /* flextile, flip master and stack areas */ + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) + TAGKEYS( XK_4, 3) + TAGKEYS( XK_5, 4) + TAGKEYS( XK_6, 5) + TAGKEYS( XK_7, 6) + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) }; /* button definitions */ diff --git a/dwm.c b/dwm.c index fd1a0eb..9cb588b 100644 --- a/dwm.c +++ b/dwm.c @@ -143,6 +143,7 @@ typedef struct Client Client; struct Client { char name[256]; float mina, maxa; + float cfact; int x, y, w, h; int oldx, oldy, oldw, oldh; int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; @@ -188,6 +189,10 @@ struct Monitor { int num; int mx, my, mw, mh; /* screen size */ int wx, wy, ww, wh; /* window area */ + int gappih; /* horizontal gap between windows */ + int gappiv; /* vertical gap between windows */ + int gappoh; /* horizontal outer gaps */ + int gappov; /* vertical outer gaps */ unsigned int seltags; unsigned int sellt; unsigned int tagset[2]; @@ -277,6 +282,7 @@ static void setclientstate(Client *c, long state); static void setfocus(Client *c); static void setfullscreen(Client *c, int fullscreen); static void setlayout(const Arg *arg); +static void setcfact(const Arg *arg); static void setmfact(const Arg *arg); static void setup(void); static void seturgent(Client *c, int urg); @@ -312,6 +318,7 @@ static void zoom(const Arg *arg); #include "libs/bar/include.h" #include "libs/lt/tile.h" +#include "libs/gaps.h" /* variables */ static const char broken[] = "broken"; @@ -373,6 +380,7 @@ struct Pertag { Client *prevzooms[LENGTH(tags) + 1]; /* store zoom information */ }; +#include "libs/gaps.c" #include "libs/lt/tile.c" /* compile-time check if all tags fit into an unsigned int bit array. */ @@ -904,6 +912,10 @@ createmon(void) m->nmaster = nmaster; m->nstack = nstack; m->showbar = showbar; + m->gappih = gappih; + m->gappiv = gappiv; + m->gappoh = gappoh; + m->gappov = gappov; for (mi = 0, mon = mons; mon; mon = mon->next, mi++); // monitor index m->lt[0] = &layouts[0]; @@ -1449,6 +1461,7 @@ manage(Window w, XWindowAttributes *wa) c->w = c->oldw = wa->width; c->h = c->oldh = wa->height; c->oldbw = wa->border_width; + c->cfact = 1.0; updatetitle(c); if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { @@ -2024,6 +2037,24 @@ setlayout(const Arg *arg) drawbar(selmon); } +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); +} + /* arg > 1.0 will set mfact absolutely */ void setmfact(const Arg *arg) diff --git a/libs/gaps.c b/libs/gaps.c new file mode 100644 index 0000000..cd96cd2 --- /dev/null +++ b/libs/gaps.c @@ -0,0 +1,143 @@ +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); +} + +void +defaultgaps(const Arg *arg) +{ + setgaps(gappoh, gappov, gappih, gappiv); +} + +void +incrgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh + arg->i, + selmon->gappov + arg->i, + selmon->gappih + arg->i, + selmon->gappiv + arg->i + ); +} + +void +incrigaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov, + selmon->gappih + arg->i, + selmon->gappiv + arg->i + ); +} + +void +incrogaps(const Arg *arg) +{ + setgaps( + selmon->gappoh + arg->i, + selmon->gappov + arg->i, + selmon->gappih, + selmon->gappiv + ); +} + +void +incrohgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh + arg->i, + selmon->gappov, + selmon->gappih, + selmon->gappiv + ); +} + +void +incrovgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov + arg->i, + selmon->gappih, + selmon->gappiv + ); +} + +void +incrihgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov, + selmon->gappih + arg->i, + selmon->gappiv + ); +} + +void +incrivgaps(const Arg *arg) +{ + setgaps( + selmon->gappoh, + selmon->gappov, + selmon->gappih, + selmon->gappiv + arg->i + ); +} + +void +getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc) +{ + unsigned int n, oe, ie; + Client *c; + + oe = ie = 1; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + 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 +} + +void +getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr) +{ + unsigned int n; + float mfacts = 0, sfacts = 0; + int mtotal = 0, stotal = 0; + 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; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) + if (n < m->nmaster) + mtotal += msize * (c->cfact / mfacts); + else + stotal += ssize * (c->cfact / sfacts); + + *mf = mfacts; // total factor of master area + *sf = sfacts; // total factor of stack area + *mr = msize - mtotal; // the remainder (rest) of pixels after a cfacts master split + *sr = ssize - stotal; // the remainder (rest) of pixels after a cfacts stack split +} diff --git a/libs/gaps.h b/libs/gaps.h new file mode 100644 index 0000000..fdd137a --- /dev/null +++ b/libs/gaps.h @@ -0,0 +1,12 @@ +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); +static void getgaps(Monitor *m, int *oh, int *ov, int *ih, int *iv, unsigned int *nc); +static void getfacts(Monitor *m, int msize, int ssize, float *mf, float *sf, int *mr, int *sr); +static void setgaps(int oh, int ov, int ih, int iv); diff --git a/libs/lt/tile.c b/libs/lt/tile.c index 9c54302..4f83c7b 100644 --- a/libs/lt/tile.c +++ b/libs/lt/tile.c @@ -721,12 +721,7 @@ flextile(Monitor *m) unsigned int n; int oh = 0, ov = 0, ih = 0, iv = 0; // gaps outer/inner horizontal/vertical - #if VANITYGAPS_PATCH getgaps(m, &oh, &ov, &ih, &iv, &n); - #else - Client *c; - for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); - #endif // VANITYGAPS_PATCH if (m->lt[m->sellt]->preset.layout != m->ltaxis[LAYOUT] || m->lt[m->sellt]->preset.masteraxis != m->ltaxis[MASTER] || @@ -739,13 +734,11 @@ flextile(Monitor *m) if (n == 0) return; - #if VANITYGAPS_PATCH && !VANITYGAPS_MONOCLE_PATCH /* No outer gap if full screen monocle */ - if (abs(m->ltaxis[MASTER]) == MONOCLE && (abs(m->ltaxis[LAYOUT]) == NO_SPLIT || n <= m->nmaster)) { + if (monoclenogaps && abs(m->ltaxis[MASTER]) == MONOCLE && (abs(m->ltaxis[LAYOUT]) == NO_SPLIT || n <= m->nmaster)) { oh = 0; ov = 0; } - #endif // VANITYGAPS_PATCH && !VANITYGAPS_MONOCLE_PATCH (&flexlayouts[abs(m->ltaxis[LAYOUT])])->arrange(m, m->wx + ov, m->wy + oh, m->wh - 2*oh, m->ww - 2*ov, ih, iv, n); return; @@ -858,4 +851,4 @@ incnstack(const Arg *arg) { selmon->nstack = selmon->pertag->nstacks[selmon->pertag->curtag] = MAX(selmon->nstack + arg->i, 0); arrange(selmon); -} \ No newline at end of file +}