apply patch upto and including patch 4
This commit is contained in:
parent
cb3f58ad06
commit
fdd2b314fa
49
config.def.h
49
config.def.h
|
@ -3,6 +3,11 @@
|
||||||
/* appearance */
|
/* appearance */
|
||||||
static const unsigned int borderpx = 1; /* border pixel of windows */
|
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
static const unsigned int snap = 32; /* snap pixel */
|
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 showbar = 1; /* 0 means no bar */
|
||||||
static const int topbar = 1; /* 0 means bottom bar */
|
static const int topbar = 1; /* 0 means bottom bar */
|
||||||
static const char *fonts[] = { "monospace:size=10" };
|
static const char *fonts[] = { "monospace:size=10" };
|
||||||
|
@ -26,9 +31,10 @@ static const Rule rules[] = {
|
||||||
* WM_CLASS(STRING) = instance, class
|
* WM_CLASS(STRING) = instance, class
|
||||||
* WM_NAME(STRING) = title
|
* WM_NAME(STRING) = title
|
||||||
*/
|
*/
|
||||||
/* class instance title tags mask isfloating monitor */
|
/* class instance title tags mask isfloating monitor scratch keys float x,y,w,h floatborderpx*/
|
||||||
{ "Gimp", NULL, NULL, 0, 1, -1 },
|
{ "Gimp", NULL, NULL, 0, 1, -1, 0, 50,50,500,500, 5 },
|
||||||
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
{ "firefox", NULL, NULL, 1 << 8, 0, -1, 0, 50,50,500,500, 5 },
|
||||||
|
{ NULL, NULL, "scratchpad", 0, 1, -1, 's', 50,50,500,500, 5 },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* layout(s) */
|
/* layout(s) */
|
||||||
|
@ -36,11 +42,26 @@ static const float mfact = 0.55; /* factor of master area size [0.05..0.95]
|
||||||
static const int nmaster = 1; /* number of clients in master area */
|
static const int nmaster = 1; /* number of clients in master area */
|
||||||
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
||||||
|
|
||||||
|
#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */
|
||||||
|
#include "vanitygaps.c"
|
||||||
|
|
||||||
static const Layout layouts[] = {
|
static const Layout layouts[] = {
|
||||||
/* symbol arrange function */
|
/* symbol arrange function */
|
||||||
{ "[]=", tile }, /* first entry is default */
|
{ "[]=", tile }, /* first entry is default */
|
||||||
{ "><>", NULL }, /* no layout function means floating behavior */
|
|
||||||
{ "[M]", monocle },
|
{ "[M]", monocle },
|
||||||
|
{ "[@]", spiral },
|
||||||
|
{ "[\\]", dwindle },
|
||||||
|
{ "H[]", deck },
|
||||||
|
{ "TTT", bstack },
|
||||||
|
{ "===", bstackhoriz },
|
||||||
|
{ "HHH", grid },
|
||||||
|
{ "###", nrowgrid },
|
||||||
|
{ "---", horizgrid },
|
||||||
|
{ ":::", gaplessgrid },
|
||||||
|
{ "|M|", centeredmaster },
|
||||||
|
{ ">M>", centeredfloatingmaster },
|
||||||
|
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||||
|
{ NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* key definitions */
|
/* key definitions */
|
||||||
|
@ -59,10 +80,14 @@ static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn()
|
||||||
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
|
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
|
||||||
static const char *termcmd[] = { "st", NULL };
|
static const char *termcmd[] = { "st", NULL };
|
||||||
|
|
||||||
|
/*First arg only serves to match against key in rules*/
|
||||||
|
static const char *scratchpadcmd[] = {"s", "st", "-t", "scratchpad", NULL};
|
||||||
|
|
||||||
static Key keys[] = {
|
static Key keys[] = {
|
||||||
/* modifier key function argument */
|
/* modifier key function argument */
|
||||||
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
||||||
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
||||||
|
{ MODKEY, XK_grave, togglescratch, {.v = scratchpadcmd } },
|
||||||
{ MODKEY, XK_b, togglebar, {0} },
|
{ MODKEY, XK_b, togglebar, {0} },
|
||||||
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
||||||
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
||||||
|
@ -71,6 +96,22 @@ static Key keys[] = {
|
||||||
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
||||||
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
|
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
|
||||||
{ MODKEY, XK_Return, zoom, {0} },
|
{ MODKEY, XK_Return, zoom, {0} },
|
||||||
|
{ 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} },
|
||||||
{ MODKEY, XK_Tab, view, {0} },
|
{ MODKEY, XK_Tab, view, {0} },
|
||||||
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
|
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
|
||||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
||||||
|
|
113
dwm.c
113
dwm.c
|
@ -93,6 +93,8 @@ struct Client {
|
||||||
int bw, oldbw;
|
int bw, oldbw;
|
||||||
unsigned int tags;
|
unsigned int tags;
|
||||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||||
|
int floatborderpx;
|
||||||
|
char scratchkey;
|
||||||
Client *next;
|
Client *next;
|
||||||
Client *snext;
|
Client *snext;
|
||||||
Monitor *mon;
|
Monitor *mon;
|
||||||
|
@ -119,6 +121,10 @@ struct Monitor {
|
||||||
int by; /* bar geometry */
|
int by; /* bar geometry */
|
||||||
int mx, my, mw, mh; /* screen size */
|
int mx, my, mw, mh; /* screen size */
|
||||||
int wx, wy, ww, wh; /* window area */
|
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 seltags;
|
||||||
unsigned int sellt;
|
unsigned int sellt;
|
||||||
unsigned int tagset[2];
|
unsigned int tagset[2];
|
||||||
|
@ -139,6 +145,9 @@ typedef struct {
|
||||||
unsigned int tags;
|
unsigned int tags;
|
||||||
int isfloating;
|
int isfloating;
|
||||||
int monitor;
|
int monitor;
|
||||||
|
const char scratchkey;
|
||||||
|
int floatx, floaty, floatw, floath;
|
||||||
|
int floatborderpx;
|
||||||
} Rule;
|
} Rule;
|
||||||
|
|
||||||
/* function declarations */
|
/* function declarations */
|
||||||
|
@ -206,11 +215,12 @@ static void seturgent(Client *c, int urg);
|
||||||
static void showhide(Client *c);
|
static void showhide(Client *c);
|
||||||
static void sigchld(int unused);
|
static void sigchld(int unused);
|
||||||
static void spawn(const Arg *arg);
|
static void spawn(const Arg *arg);
|
||||||
|
static void spawnscratch(const Arg *arg);
|
||||||
static void tag(const Arg *arg);
|
static void tag(const Arg *arg);
|
||||||
static void tagmon(const Arg *arg);
|
static void tagmon(const Arg *arg);
|
||||||
static void tile(Monitor *);
|
|
||||||
static void togglebar(const Arg *arg);
|
static void togglebar(const Arg *arg);
|
||||||
static void togglefloating(const Arg *arg);
|
static void togglefloating(const Arg *arg);
|
||||||
|
static void togglescratch(const Arg *arg);
|
||||||
static void toggletag(const Arg *arg);
|
static void toggletag(const Arg *arg);
|
||||||
static void toggleview(const Arg *arg);
|
static void toggleview(const Arg *arg);
|
||||||
static void unfocus(Client *c, int setfocus);
|
static void unfocus(Client *c, int setfocus);
|
||||||
|
@ -287,6 +297,7 @@ applyrules(Client *c)
|
||||||
/* rule matching */
|
/* rule matching */
|
||||||
c->isfloating = 0;
|
c->isfloating = 0;
|
||||||
c->tags = 0;
|
c->tags = 0;
|
||||||
|
c->scratchkey = 0;
|
||||||
XGetClassHint(dpy, c->win, &ch);
|
XGetClassHint(dpy, c->win, &ch);
|
||||||
class = ch.res_class ? ch.res_class : broken;
|
class = ch.res_class ? ch.res_class : broken;
|
||||||
instance = ch.res_name ? ch.res_name : broken;
|
instance = ch.res_name ? ch.res_name : broken;
|
||||||
|
@ -299,6 +310,14 @@ applyrules(Client *c)
|
||||||
{
|
{
|
||||||
c->isfloating = r->isfloating;
|
c->isfloating = r->isfloating;
|
||||||
c->tags |= r->tags;
|
c->tags |= r->tags;
|
||||||
|
c->floatborderpx = r->floatborderpx;
|
||||||
|
if (r->isfloating) {
|
||||||
|
c->x = r->floatx;
|
||||||
|
c->y = r->floaty;
|
||||||
|
c->w = r->floatw;
|
||||||
|
c->h = r->floath;
|
||||||
|
}
|
||||||
|
c->scratchkey = r->scratchkey;
|
||||||
for (m = mons; m && m->num != r->monitor; m = m->next);
|
for (m = mons; m && m->num != r->monitor; m = m->next);
|
||||||
if (m)
|
if (m)
|
||||||
c->mon = m;
|
c->mon = m;
|
||||||
|
@ -308,6 +327,7 @@ applyrules(Client *c)
|
||||||
XFree(ch.res_class);
|
XFree(ch.res_class);
|
||||||
if (ch.res_name)
|
if (ch.res_name)
|
||||||
XFree(ch.res_name);
|
XFree(ch.res_name);
|
||||||
|
|
||||||
c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
|
c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +436,7 @@ attachstack(Client *c)
|
||||||
void
|
void
|
||||||
buttonpress(XEvent *e)
|
buttonpress(XEvent *e)
|
||||||
{
|
{
|
||||||
unsigned int i, x, click;
|
unsigned int i, x, click, occ = 0;
|
||||||
Arg arg = {0};
|
Arg arg = {0};
|
||||||
Client *c;
|
Client *c;
|
||||||
Monitor *m;
|
Monitor *m;
|
||||||
|
@ -431,9 +451,14 @@ buttonpress(XEvent *e)
|
||||||
}
|
}
|
||||||
if (ev->window == selmon->barwin) {
|
if (ev->window == selmon->barwin) {
|
||||||
i = x = 0;
|
i = x = 0;
|
||||||
do
|
for (c = m->clients; c; c = c->next)
|
||||||
|
occ |= c->tags == 255 ? 0 : c->tags;
|
||||||
|
do {
|
||||||
|
/* do not reserve space for vacant tags */
|
||||||
|
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
|
||||||
|
continue;
|
||||||
x += TEXTW(tags[i]);
|
x += TEXTW(tags[i]);
|
||||||
while (ev->x >= x && ++i < LENGTH(tags));
|
} while (ev->x >= x && ++i < LENGTH(tags));
|
||||||
if (i < LENGTH(tags)) {
|
if (i < LENGTH(tags)) {
|
||||||
click = ClkTagBar;
|
click = ClkTagBar;
|
||||||
arg.ui = 1 << i;
|
arg.ui = 1 << i;
|
||||||
|
@ -638,6 +663,10 @@ createmon(void)
|
||||||
m->nmaster = nmaster;
|
m->nmaster = nmaster;
|
||||||
m->showbar = showbar;
|
m->showbar = showbar;
|
||||||
m->topbar = topbar;
|
m->topbar = topbar;
|
||||||
|
m->gappih = gappih;
|
||||||
|
m->gappiv = gappiv;
|
||||||
|
m->gappoh = gappoh;
|
||||||
|
m->gappov = gappov;
|
||||||
m->lt[0] = &layouts[0];
|
m->lt[0] = &layouts[0];
|
||||||
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
||||||
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
||||||
|
@ -709,19 +738,19 @@ drawbar(Monitor *m)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (c = m->clients; c; c = c->next) {
|
for (c = m->clients; c; c = c->next) {
|
||||||
occ |= c->tags;
|
occ |= c->tags == 255 ? 0 : c->tags;
|
||||||
if (c->isurgent)
|
if (c->isurgent)
|
||||||
urg |= c->tags;
|
urg |= c->tags;
|
||||||
}
|
}
|
||||||
x = 0;
|
x = 0;
|
||||||
for (i = 0; i < LENGTH(tags); i++) {
|
for (i = 0; i < LENGTH(tags); i++) {
|
||||||
|
/* do not draw vacant tags */
|
||||||
|
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
|
||||||
|
continue;
|
||||||
|
|
||||||
w = TEXTW(tags[i]);
|
w = TEXTW(tags[i]);
|
||||||
drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
|
drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
|
||||||
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
|
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
|
||||||
if (occ & 1 << i)
|
|
||||||
drw_rect(drw, x + boxs, boxs, boxw, boxw,
|
|
||||||
m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
|
|
||||||
urg & 1 << i);
|
|
||||||
x += w;
|
x += w;
|
||||||
}
|
}
|
||||||
w = blw = TEXTW(m->ltsymbol);
|
w = blw = TEXTW(m->ltsymbol);
|
||||||
|
@ -1281,7 +1310,10 @@ resizeclient(Client *c, int x, int y, int w, int h)
|
||||||
c->oldy = c->y; c->y = wc.y = y;
|
c->oldy = c->y; c->y = wc.y = y;
|
||||||
c->oldw = c->w; c->w = wc.width = w;
|
c->oldw = c->w; c->w = wc.width = w;
|
||||||
c->oldh = c->h; c->h = wc.height = h;
|
c->oldh = c->h; c->h = wc.height = h;
|
||||||
wc.border_width = c->bw;
|
if (c->isfloating)
|
||||||
|
wc.border_width = c->floatborderpx;
|
||||||
|
else
|
||||||
|
wc.border_width = c->bw;
|
||||||
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
|
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
|
||||||
configure(c);
|
configure(c);
|
||||||
XSync(dpy, False);
|
XSync(dpy, False);
|
||||||
|
@ -1652,6 +1684,19 @@ spawn(const Arg *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void spawnscratch(const Arg *arg)
|
||||||
|
{
|
||||||
|
if (fork() == 0) {
|
||||||
|
if (dpy)
|
||||||
|
close(ConnectionNumber(dpy));
|
||||||
|
setsid();
|
||||||
|
execvp(((char **)arg->v)[1], ((char **)arg->v)+1);
|
||||||
|
fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[1]);
|
||||||
|
perror(" failed");
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tag(const Arg *arg)
|
tag(const Arg *arg)
|
||||||
{
|
{
|
||||||
|
@ -1670,32 +1715,6 @@ tagmon(const Arg *arg)
|
||||||
sendmon(selmon->sel, dirtomon(arg->i));
|
sendmon(selmon->sel, dirtomon(arg->i));
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
void
|
||||||
togglebar(const Arg *arg)
|
togglebar(const Arg *arg)
|
||||||
{
|
{
|
||||||
|
@ -1719,6 +1738,28 @@ togglefloating(const Arg *arg)
|
||||||
arrange(selmon);
|
arrange(selmon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
togglescratch(const Arg *arg)
|
||||||
|
{
|
||||||
|
Client *c;
|
||||||
|
unsigned int found = 0;
|
||||||
|
|
||||||
|
for (c = selmon->clients; c && !(found = c->scratchkey == ((char**)arg->v)[0][0]); c = c->next);
|
||||||
|
if (found) {
|
||||||
|
c->tags = ISVISIBLE(c) ? 0 : selmon->tagset[selmon->seltags];
|
||||||
|
focus(NULL);
|
||||||
|
arrange(selmon);
|
||||||
|
|
||||||
|
if (ISVISIBLE(c)) {
|
||||||
|
focus(c);
|
||||||
|
restack(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else{
|
||||||
|
spawnscratch(arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
toggletag(const Arg *arg)
|
toggletag(const Arg *arg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
diff '--color=auto' -up dwm-6.2/config.def.h dwm-6.2-new/config.def.h
|
||||||
|
--- dwm-6.2/config.def.h 2019-02-02 12:55:28.000000000 +0000
|
||||||
|
+++ dwm-6.2-new/config.def.h 2020-04-26 13:51:06.713332746 +0100
|
||||||
|
@@ -26,9 +26,10 @@ static const Rule rules[] = {
|
||||||
|
* WM_CLASS(STRING) = instance, class
|
||||||
|
* WM_NAME(STRING) = title
|
||||||
|
*/
|
||||||
|
- /* class instance title tags mask isfloating monitor */
|
||||||
|
- { "Gimp", NULL, NULL, 0, 1, -1 },
|
||||||
|
- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
||||||
|
+ /* class instance title tags mask isfloating monitor scratch key */
|
||||||
|
+ { "Gimp", NULL, NULL, 0, 1, -1, 0 },
|
||||||
|
+ { "firefox", NULL, NULL, 1 << 8, 0, -1, 0 },
|
||||||
|
+ { NULL, NULL, "scratchpad", 0, 1, -1, 's' },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* layout(s) */
|
||||||
|
@@ -59,10 +60,14 @@ static char dmenumon[2] = "0"; /* compon
|
||||||
|
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
|
||||||
|
static const char *termcmd[] = { "st", NULL };
|
||||||
|
|
||||||
|
+/*First arg only serves to match against key in rules*/
|
||||||
|
+static const char *scratchpadcmd[] = {"s", "st", "-t", "scratchpad", NULL};
|
||||||
|
+
|
||||||
|
static Key keys[] = {
|
||||||
|
/* modifier key function argument */
|
||||||
|
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
|
||||||
|
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
|
||||||
|
+ { MODKEY, XK_grave, togglescratch, {.v = scratchpadcmd } },
|
||||||
|
{ MODKEY, XK_b, togglebar, {0} },
|
||||||
|
{ MODKEY, XK_j, focusstack, {.i = +1 } },
|
||||||
|
{ MODKEY, XK_k, focusstack, {.i = -1 } },
|
||||||
|
diff '--color=auto' -up dwm-6.2/dwm.c dwm-6.2-new/dwm.c
|
||||||
|
--- dwm-6.2/dwm.c 2019-02-02 12:55:28.000000000 +0000
|
||||||
|
+++ dwm-6.2-new/dwm.c 2020-04-26 13:55:56.820584361 +0100
|
||||||
|
@@ -93,6 +93,7 @@ struct Client {
|
||||||
|
int bw, oldbw;
|
||||||
|
unsigned int tags;
|
||||||
|
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||||
|
+ char scratchkey;
|
||||||
|
Client *next;
|
||||||
|
Client *snext;
|
||||||
|
Monitor *mon;
|
||||||
|
@@ -139,6 +140,7 @@ typedef struct {
|
||||||
|
unsigned int tags;
|
||||||
|
int isfloating;
|
||||||
|
int monitor;
|
||||||
|
+ const char scratchkey;
|
||||||
|
} Rule;
|
||||||
|
|
||||||
|
/* function declarations */
|
||||||
|
@@ -206,11 +208,13 @@ static void seturgent(Client *c, int urg
|
||||||
|
static void showhide(Client *c);
|
||||||
|
static void sigchld(int unused);
|
||||||
|
static void spawn(const Arg *arg);
|
||||||
|
+static void spawnscratch(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 togglescratch(const Arg *arg);
|
||||||
|
static void toggletag(const Arg *arg);
|
||||||
|
static void toggleview(const Arg *arg);
|
||||||
|
static void unfocus(Client *c, int setfocus);
|
||||||
|
@@ -287,6 +291,7 @@ applyrules(Client *c)
|
||||||
|
/* rule matching */
|
||||||
|
c->isfloating = 0;
|
||||||
|
c->tags = 0;
|
||||||
|
+ c->scratchkey = 0;
|
||||||
|
XGetClassHint(dpy, c->win, &ch);
|
||||||
|
class = ch.res_class ? ch.res_class : broken;
|
||||||
|
instance = ch.res_name ? ch.res_name : broken;
|
||||||
|
@@ -299,6 +304,7 @@ applyrules(Client *c)
|
||||||
|
{
|
||||||
|
c->isfloating = r->isfloating;
|
||||||
|
c->tags |= r->tags;
|
||||||
|
+ c->scratchkey = r->scratchkey;
|
||||||
|
for (m = mons; m && m->num != r->monitor; m = m->next);
|
||||||
|
if (m)
|
||||||
|
c->mon = m;
|
||||||
|
@@ -308,6 +314,7 @@ applyrules(Client *c)
|
||||||
|
XFree(ch.res_class);
|
||||||
|
if (ch.res_name)
|
||||||
|
XFree(ch.res_name);
|
||||||
|
+
|
||||||
|
c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1652,6 +1659,19 @@ spawn(const Arg *arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void spawnscratch(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ if (fork() == 0) {
|
||||||
|
+ if (dpy)
|
||||||
|
+ close(ConnectionNumber(dpy));
|
||||||
|
+ setsid();
|
||||||
|
+ execvp(((char **)arg->v)[1], ((char **)arg->v)+1);
|
||||||
|
+ fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[1]);
|
||||||
|
+ perror(" failed");
|
||||||
|
+ exit(EXIT_SUCCESS);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
tag(const Arg *arg)
|
||||||
|
{
|
||||||
|
@@ -1720,6 +1740,28 @@ togglefloating(const Arg *arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
+togglescratch(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ Client *c;
|
||||||
|
+ unsigned int found = 0;
|
||||||
|
+
|
||||||
|
+ for (c = selmon->clients; c && !(found = c->scratchkey == ((char**)arg->v)[0][0]); c = c->next);
|
||||||
|
+ if (found) {
|
||||||
|
+ c->tags = ISVISIBLE(c) ? 0 : selmon->tagset[selmon->seltags];
|
||||||
|
+ focus(NULL);
|
||||||
|
+ arrange(selmon);
|
||||||
|
+
|
||||||
|
+ if (ISVISIBLE(c)) {
|
||||||
|
+ focus(c);
|
||||||
|
+ restack(selmon);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ } else{
|
||||||
|
+ spawnscratch(arg);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
toggletag(const Arg *arg)
|
||||||
|
{
|
||||||
|
unsigned int newtags;
|
|
@ -0,0 +1,971 @@
|
||||||
|
From 9709d08daa290c8c7319571cd9e6ef4ec40e7683 Mon Sep 17 00:00:00 2001
|
||||||
|
From: bakkeby <bakkeby@gmail.com>
|
||||||
|
Date: Wed, 6 May 2020 17:21:25 +0200
|
||||||
|
Subject: [PATCH] vanitygaps - adds gaps to layouts
|
||||||
|
|
||||||
|
This patch differentiates between inner and outer gaps as well as
|
||||||
|
horizontal and vertical gaps.
|
||||||
|
|
||||||
|
The logic of these layouts also aims to be pixel perfect by ensuring
|
||||||
|
an even split of the available space and re-distributing the remainder
|
||||||
|
among the available clients.
|
||||||
|
---
|
||||||
|
config.def.h | 38 ++-
|
||||||
|
dwm.c | 35 +--
|
||||||
|
vanitygaps.c | 809 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 854 insertions(+), 28 deletions(-)
|
||||||
|
create mode 100644 vanitygaps.c
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..a886863 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.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 char *fonts[] = { "monospace:size=10" };
|
||||||
|
@@ -36,11 +41,26 @@ static const float mfact = 0.55; /* factor of master area size [0.05..0.95]
|
||||||
|
static const int nmaster = 1; /* number of clients in master area */
|
||||||
|
static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */
|
||||||
|
|
||||||
|
+#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */
|
||||||
|
+#include "vanitygaps.c"
|
||||||
|
+
|
||||||
|
static const Layout layouts[] = {
|
||||||
|
/* symbol arrange function */
|
||||||
|
{ "[]=", tile }, /* first entry is default */
|
||||||
|
- { "><>", NULL }, /* no layout function means floating behavior */
|
||||||
|
{ "[M]", monocle },
|
||||||
|
+ { "[@]", spiral },
|
||||||
|
+ { "[\\]", dwindle },
|
||||||
|
+ { "H[]", deck },
|
||||||
|
+ { "TTT", bstack },
|
||||||
|
+ { "===", bstackhoriz },
|
||||||
|
+ { "HHH", grid },
|
||||||
|
+ { "###", nrowgrid },
|
||||||
|
+ { "---", horizgrid },
|
||||||
|
+ { ":::", gaplessgrid },
|
||||||
|
+ { "|M|", centeredmaster },
|
||||||
|
+ { ">M>", centeredfloatingmaster },
|
||||||
|
+ { "><>", NULL }, /* no layout function means floating behavior */
|
||||||
|
+ { NULL, NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* key definitions */
|
||||||
|
@@ -71,6 +91,22 @@ static Key keys[] = {
|
||||||
|
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
|
||||||
|
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
|
||||||
|
{ MODKEY, XK_Return, zoom, {0} },
|
||||||
|
+ { 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} },
|
||||||
|
{ 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 4465af1..c3b2d82 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -119,6 +119,10 @@ struct Monitor {
|
||||||
|
int by; /* bar geometry */
|
||||||
|
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];
|
||||||
|
@@ -208,7 +212,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);
|
||||||
|
@@ -638,6 +641,10 @@ createmon(void)
|
||||||
|
m->nmaster = nmaster;
|
||||||
|
m->showbar = showbar;
|
||||||
|
m->topbar = topbar;
|
||||||
|
+ m->gappih = gappih;
|
||||||
|
+ m->gappiv = gappiv;
|
||||||
|
+ m->gappoh = gappoh;
|
||||||
|
+ m->gappov = gappov;
|
||||||
|
m->lt[0] = &layouts[0];
|
||||||
|
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
||||||
|
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
||||||
|
@@ -1670,32 +1677,6 @@ tagmon(const Arg *arg)
|
||||||
|
sendmon(selmon->sel, dirtomon(arg->i));
|
||||||
|
}
|
||||||
|
|
||||||
|
-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/vanitygaps.c b/vanitygaps.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..3f31593
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/vanitygaps.c
|
||||||
|
@@ -0,0 +1,809 @@
|
||||||
|
+/* 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);
|
||||||
|
+/* Layouts (delete the ones you do not need) */
|
||||||
|
+static void bstack(Monitor *m);
|
||||||
|
+static void bstackhoriz(Monitor *m);
|
||||||
|
+static void centeredmaster(Monitor *m);
|
||||||
|
+static void centeredfloatingmaster(Monitor *m);
|
||||||
|
+static void deck(Monitor *m);
|
||||||
|
+static void dwindle(Monitor *m);
|
||||||
|
+static void fibonacci(Monitor *m, int s);
|
||||||
|
+static void grid(Monitor *m);
|
||||||
|
+static void nrowgrid(Monitor *m);
|
||||||
|
+static void spiral(Monitor *m);
|
||||||
|
+static void tile(Monitor *m);
|
||||||
|
+/* Internals */
|
||||||
|
+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);
|
||||||
|
+
|
||||||
|
+/* Settings */
|
||||||
|
+#if !PERTAG_PATCH
|
||||||
|
+static int enablegaps = 1;
|
||||||
|
+#endif // PERTAG_PATCH
|
||||||
|
+
|
||||||
|
+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
|
||||||
|
+togglegaps(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ #if PERTAG_PATCH
|
||||||
|
+ selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag];
|
||||||
|
+ #else
|
||||||
|
+ enablegaps = !enablegaps;
|
||||||
|
+ #endif // PERTAG_PATCH
|
||||||
|
+ arrange(NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+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;
|
||||||
|
+ #if PERTAG_PATCH
|
||||||
|
+ oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag];
|
||||||
|
+ #else
|
||||||
|
+ oe = ie = enablegaps;
|
||||||
|
+ #endif // PERTAG_PATCH
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ 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, sfacts;
|
||||||
|
+ int mtotal = 0, stotal = 0;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
||||||
|
+ mfacts = MIN(n, m->nmaster);
|
||||||
|
+ sfacts = n - m->nmaster;
|
||||||
|
+
|
||||||
|
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
|
||||||
|
+ if (n < m->nmaster)
|
||||||
|
+ mtotal += msize / mfacts;
|
||||||
|
+ else
|
||||||
|
+ stotal += ssize / sfacts;
|
||||||
|
+
|
||||||
|
+ *mf = mfacts; // total factor of master area
|
||||||
|
+ *sf = sfacts; // total factor of stack area
|
||||||
|
+ *mr = msize - mtotal; // the remainder (rest) of pixels after an even master split
|
||||||
|
+ *sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/***
|
||||||
|
+ * Layouts
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Bottomstack layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/bottomstack/
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+bstack(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
+ float mfacts, sfacts;
|
||||||
|
+ int mrest, srest;
|
||||||
|
+ 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;
|
||||||
|
+ mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
|
||||||
|
+ sw = m->ww - 2*ov - iv * (n - m->nmaster - 1);
|
||||||
|
+
|
||||||
|
+ if (m->nmaster && n > m->nmaster) {
|
||||||
|
+ sh = (mh - ih) * (1 - m->mfact);
|
||||||
|
+ mh = mh - ih - sh;
|
||||||
|
+ sx = mx;
|
||||||
|
+ sy = my + mh + ih;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
+ if (i < m->nmaster) {
|
||||||
|
+ resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
+ mx += WIDTH(c) + iv;
|
||||||
|
+ } else {
|
||||||
|
+ resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
+ sx += WIDTH(c) + iv;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+bstackhoriz(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
+ float mfacts, sfacts;
|
||||||
|
+ int mrest, srest;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ sx = mx = m->wx + ov;
|
||||||
|
+ sy = my = m->wy + oh;
|
||||||
|
+ mh = m->wh - 2*oh;
|
||||||
|
+ sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
|
||||||
|
+ mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
|
||||||
|
+ sw = m->ww - 2*ov;
|
||||||
|
+
|
||||||
|
+ if (m->nmaster && n > m->nmaster) {
|
||||||
|
+ sh = (mh - ih) * (1 - m->mfact);
|
||||||
|
+ mh = mh - ih - sh;
|
||||||
|
+ sy = my + mh + ih;
|
||||||
|
+ sh = m->wh - mh - 2*oh - ih * (n - m->nmaster);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
+ if (i < m->nmaster) {
|
||||||
|
+ resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
+ mx += WIDTH(c) + iv;
|
||||||
|
+ } else {
|
||||||
|
+ resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ sy += HEIGHT(c) + ih;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Centred master layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/centeredmaster/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+centeredmaster(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int lx = 0, ly = 0, lw = 0, lh = 0;
|
||||||
|
+ int rx = 0, ry = 0, rw = 0, rh = 0;
|
||||||
|
+ float mfacts = 0, lfacts = 0, rfacts = 0;
|
||||||
|
+ int mtotal = 0, ltotal = 0, rtotal = 0;
|
||||||
|
+ int mrest = 0, lrest = 0, rrest = 0;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* initialize areas */
|
||||||
|
+ mx = m->wx + ov;
|
||||||
|
+ my = m->wy + oh;
|
||||||
|
+ mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1);
|
||||||
|
+ mw = m->ww - 2*ov;
|
||||||
|
+ lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1);
|
||||||
|
+ rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1));
|
||||||
|
+
|
||||||
|
+ if (m->nmaster && n > m->nmaster) {
|
||||||
|
+ /* go mfact box in the center if more than nmaster clients */
|
||||||
|
+ if (n - m->nmaster > 1) {
|
||||||
|
+ /* ||<-S->|<---M--->|<-S->|| */
|
||||||
|
+ mw = (m->ww - 2*ov - 2*iv) * m->mfact;
|
||||||
|
+ lw = (m->ww - mw - 2*ov - 2*iv) / 2;
|
||||||
|
+ rw = (m->ww - mw - 2*ov - 2*iv) - lw;
|
||||||
|
+ mx += lw + iv;
|
||||||
|
+ } else {
|
||||||
|
+ /* ||<---M--->|<-S->|| */
|
||||||
|
+ mw = (mw - iv) * m->mfact;
|
||||||
|
+ lw = 0;
|
||||||
|
+ rw = m->ww - mw - iv - 2*ov;
|
||||||
|
+ }
|
||||||
|
+ lx = m->wx + ov;
|
||||||
|
+ ly = m->wy + oh;
|
||||||
|
+ rx = mx + mw + iv;
|
||||||
|
+ ry = m->wy + oh;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* calculate facts */
|
||||||
|
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
|
||||||
|
+ if (!m->nmaster || n < m->nmaster)
|
||||||
|
+ mfacts += 1;
|
||||||
|
+ else if ((n - m->nmaster) % 2)
|
||||||
|
+ lfacts += 1; // total factor of left hand stack area
|
||||||
|
+ else
|
||||||
|
+ rfacts += 1; // total factor of right hand stack area
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
|
||||||
|
+ if (!m->nmaster || n < m->nmaster)
|
||||||
|
+ mtotal += mh / mfacts;
|
||||||
|
+ else if ((n - m->nmaster) % 2)
|
||||||
|
+ ltotal += lh / lfacts;
|
||||||
|
+ else
|
||||||
|
+ rtotal += rh / rfacts;
|
||||||
|
+
|
||||||
|
+ mrest = mh - mtotal;
|
||||||
|
+ lrest = lh - ltotal;
|
||||||
|
+ rrest = rh - rtotal;
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
+ if (!m->nmaster || i < m->nmaster) {
|
||||||
|
+ /* nmaster clients are stacked vertically, in the center of the screen */
|
||||||
|
+ resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ my += HEIGHT(c) + ih;
|
||||||
|
+ } else {
|
||||||
|
+ /* stack clients are stacked vertically */
|
||||||
|
+ if ((i - m->nmaster) % 2 ) {
|
||||||
|
+ resize(c, lx, ly, lw - (2*c->bw), (lh / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ ly += HEIGHT(c) + ih;
|
||||||
|
+ } else {
|
||||||
|
+ resize(c, rx, ry, rw - (2*c->bw), (rh / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ ry += HEIGHT(c) + ih;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+centeredfloatingmaster(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ float mfacts, sfacts;
|
||||||
|
+ float mivf = 1.0; // master inner vertical gap factor
|
||||||
|
+ int oh, ov, ih, iv, mrest, srest;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
+ 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;
|
||||||
|
+ mw = m->ww - 2*ov - iv*(n - 1);
|
||||||
|
+ sw = m->ww - 2*ov - iv*(n - m->nmaster - 1);
|
||||||
|
+
|
||||||
|
+ if (m->nmaster && n > m->nmaster) {
|
||||||
|
+ mivf = 0.8;
|
||||||
|
+ /* go mfact box in the center if more than nmaster clients */
|
||||||
|
+ if (m->ww > m->wh) {
|
||||||
|
+ mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1);
|
||||||
|
+ mh = m->wh * 0.9;
|
||||||
|
+ } else {
|
||||||
|
+ mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1);
|
||||||
|
+ mh = m->wh * m->mfact;
|
||||||
|
+ }
|
||||||
|
+ mx = m->wx + (m->ww - mw) / 2;
|
||||||
|
+ my = m->wy + (m->wh - mh - 2*oh) / 2;
|
||||||
|
+
|
||||||
|
+ sx = m->wx + ov;
|
||||||
|
+ sy = m->wy + oh;
|
||||||
|
+ sh = m->wh - 2*oh;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
+ if (i < m->nmaster) {
|
||||||
|
+ /* nmaster clients are stacked horizontally, in the center of the screen */
|
||||||
|
+ resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
+ mx += WIDTH(c) + iv*mivf;
|
||||||
|
+ } else {
|
||||||
|
+ /* stack clients are stacked horizontally */
|
||||||
|
+ resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
+ sx += WIDTH(c) + iv;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Deck layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/deck/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+deck(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
+ float mfacts, sfacts;
|
||||||
|
+ int mrest, srest;
|
||||||
|
+ 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 - sw;
|
||||||
|
+ sx = mx + mw + iv;
|
||||||
|
+ sh = m->wh - 2*oh;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
+
|
||||||
|
+ if (n - m->nmaster > 0) /* override layout symbol */
|
||||||
|
+ snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster);
|
||||||
|
+
|
||||||
|
+ 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 / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ my += HEIGHT(c) + ih;
|
||||||
|
+ } else {
|
||||||
|
+ resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Fibonacci layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/fibonacci/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+fibonacci(Monitor *m, int s)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int nx, ny, nw, nh;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int nv, hrest = 0, wrest = 0, r = 1;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ nx = m->wx + ov;
|
||||||
|
+ ny = m->wy + oh;
|
||||||
|
+ nw = m->ww - 2*ov;
|
||||||
|
+ nh = m->wh - 2*oh;
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
|
||||||
|
+ if (r) {
|
||||||
|
+ if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw))
|
||||||
|
+ || (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) {
|
||||||
|
+ r = 0;
|
||||||
|
+ }
|
||||||
|
+ if (r && i < n - 1) {
|
||||||
|
+ if (i % 2) {
|
||||||
|
+ nv = (nh - ih) / 2;
|
||||||
|
+ hrest = nh - 2*nv - ih;
|
||||||
|
+ nh = nv;
|
||||||
|
+ } else {
|
||||||
|
+ nv = (nw - iv) / 2;
|
||||||
|
+ wrest = nw - 2*nv - iv;
|
||||||
|
+ nw = nv;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((i % 4) == 2 && !s)
|
||||||
|
+ nx += nw + iv;
|
||||||
|
+ else if ((i % 4) == 3 && !s)
|
||||||
|
+ ny += nh + ih;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if ((i % 4) == 0) {
|
||||||
|
+ if (s) {
|
||||||
|
+ ny += nh + ih;
|
||||||
|
+ nh += hrest;
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ nh -= hrest;
|
||||||
|
+ ny -= nh + ih;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else if ((i % 4) == 1) {
|
||||||
|
+ nx += nw + iv;
|
||||||
|
+ nw += wrest;
|
||||||
|
+ }
|
||||||
|
+ else if ((i % 4) == 2) {
|
||||||
|
+ ny += nh + ih;
|
||||||
|
+ nh += hrest;
|
||||||
|
+ if (i < n - 1)
|
||||||
|
+ nw += wrest;
|
||||||
|
+ }
|
||||||
|
+ else if ((i % 4) == 3) {
|
||||||
|
+ if (s) {
|
||||||
|
+ nx += nw + iv;
|
||||||
|
+ nw -= wrest;
|
||||||
|
+ } else {
|
||||||
|
+ nw -= wrest;
|
||||||
|
+ nx -= nw + iv;
|
||||||
|
+ nh += hrest;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (i == 0) {
|
||||||
|
+ if (n != 1) {
|
||||||
|
+ nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact);
|
||||||
|
+ wrest = 0;
|
||||||
|
+ }
|
||||||
|
+ ny = m->wy + oh;
|
||||||
|
+ }
|
||||||
|
+ else if (i == 1)
|
||||||
|
+ nw = m->ww - nw - iv - 2*ov;
|
||||||
|
+ i++;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+dwindle(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ fibonacci(m, 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+spiral(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ fibonacci(m, 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Gappless grid layout + gaps (ironically)
|
||||||
|
+ * https://dwm.suckless.org/patches/gaplessgrid/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+gaplessgrid(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* grid dimensions */
|
||||||
|
+ for (cols = 0; cols <= n/2; cols++)
|
||||||
|
+ if (cols*cols >= n)
|
||||||
|
+ break;
|
||||||
|
+ if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
|
||||||
|
+ cols = 2;
|
||||||
|
+ rows = n/cols;
|
||||||
|
+ cn = rn = 0; // reset column no, row no, client count
|
||||||
|
+
|
||||||
|
+ ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
|
||||||
|
+ cw = (m->ww - 2*ov - iv * (cols - 1)) / cols;
|
||||||
|
+ rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
|
||||||
|
+ crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
|
||||||
|
+ x = m->wx + ov;
|
||||||
|
+ y = m->wy + oh;
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) {
|
||||||
|
+ if (i/rows + 1 > cols - n%cols) {
|
||||||
|
+ rows = n/cols + 1;
|
||||||
|
+ ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
|
||||||
|
+ rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
|
||||||
|
+ }
|
||||||
|
+ resize(c,
|
||||||
|
+ x,
|
||||||
|
+ y + rn*(ch + ih) + MIN(rn, rrest),
|
||||||
|
+ cw + (cn < crest ? 1 : 0) - 2*c->bw,
|
||||||
|
+ ch + (rn < rrest ? 1 : 0) - 2*c->bw,
|
||||||
|
+ 0);
|
||||||
|
+ rn++;
|
||||||
|
+ if (rn >= rows) {
|
||||||
|
+ rn = 0;
|
||||||
|
+ x += cw + ih + (cn < crest ? 1 : 0);
|
||||||
|
+ cn++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Gridmode layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/gridmode/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+grid(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+
|
||||||
|
+ /* grid dimensions */
|
||||||
|
+ for (rows = 0; rows <= n/2; rows++)
|
||||||
|
+ if (rows*rows >= n)
|
||||||
|
+ break;
|
||||||
|
+ cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
|
||||||
|
+
|
||||||
|
+ /* window geoms (cell height/width) */
|
||||||
|
+ ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1);
|
||||||
|
+ cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1);
|
||||||
|
+ chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
|
||||||
|
+ cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
+ cc = i / rows;
|
||||||
|
+ cr = i % rows;
|
||||||
|
+ cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest);
|
||||||
|
+ cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest);
|
||||||
|
+ resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Horizontal grid layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/horizgrid/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+horizgrid(Monitor *m) {
|
||||||
|
+ Client *c;
|
||||||
|
+ unsigned int n, i;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
+ int ntop, nbottom = 1;
|
||||||
|
+ float mfacts, sfacts;
|
||||||
|
+ int mrest, srest;
|
||||||
|
+
|
||||||
|
+ /* Count windows */
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (n <= 2)
|
||||||
|
+ ntop = n;
|
||||||
|
+ else {
|
||||||
|
+ ntop = n / 2;
|
||||||
|
+ nbottom = n - ntop;
|
||||||
|
+ }
|
||||||
|
+ sx = mx = m->wx + ov;
|
||||||
|
+ sy = my = m->wy + oh;
|
||||||
|
+ sh = mh = m->wh - 2*oh;
|
||||||
|
+ sw = mw = m->ww - 2*ov;
|
||||||
|
+
|
||||||
|
+ if (n > ntop) {
|
||||||
|
+ sh = (mh - ih) / 2;
|
||||||
|
+ mh = mh - ih - sh;
|
||||||
|
+ sy = my + mh + ih;
|
||||||
|
+ mw = m->ww - 2*ov - iv * (ntop - 1);
|
||||||
|
+ sw = m->ww - 2*ov - iv * (nbottom - 1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ mfacts = ntop;
|
||||||
|
+ sfacts = nbottom;
|
||||||
|
+ mrest = mw - (mw / ntop) * ntop;
|
||||||
|
+ srest = sw - (sw / nbottom) * nbottom;
|
||||||
|
+
|
||||||
|
+ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
+ if (i < ntop) {
|
||||||
|
+ resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
+ mx += WIDTH(c) + iv;
|
||||||
|
+ } else {
|
||||||
|
+ resize(c, sx, sy, (sw / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
+ sx += WIDTH(c) + iv;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * nrowgrid layout + gaps
|
||||||
|
+ * https://dwm.suckless.org/patches/nrowgrid/
|
||||||
|
+ */
|
||||||
|
+void
|
||||||
|
+nrowgrid(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int n;
|
||||||
|
+ int ri = 0, ci = 0; /* counters */
|
||||||
|
+ int oh, ov, ih, iv; /* vanitygap settings */
|
||||||
|
+ unsigned int cx, cy, cw, ch; /* client geometry */
|
||||||
|
+ unsigned int uw = 0, uh = 0, uc = 0; /* utilization trackers */
|
||||||
|
+ unsigned int cols, rows = m->nmaster + 1;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ /* count clients */
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+
|
||||||
|
+ /* nothing to do here */
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* force 2 clients to always split vertically */
|
||||||
|
+ if (FORCE_VSPLIT && n == 2)
|
||||||
|
+ rows = 1;
|
||||||
|
+
|
||||||
|
+ /* never allow empty rows */
|
||||||
|
+ if (n < rows)
|
||||||
|
+ rows = n;
|
||||||
|
+
|
||||||
|
+ /* define first row */
|
||||||
|
+ cols = n / rows;
|
||||||
|
+ uc = cols;
|
||||||
|
+ cy = m->wy + oh;
|
||||||
|
+ ch = (m->wh - 2*oh - ih*(rows - 1)) / rows;
|
||||||
|
+ uh = ch;
|
||||||
|
+
|
||||||
|
+ for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) {
|
||||||
|
+ if (ci == cols) {
|
||||||
|
+ uw = 0;
|
||||||
|
+ ci = 0;
|
||||||
|
+ ri++;
|
||||||
|
+
|
||||||
|
+ /* next row */
|
||||||
|
+ cols = (n - uc) / (rows - ri);
|
||||||
|
+ uc += cols;
|
||||||
|
+ cy = m->wy + oh + uh + ih;
|
||||||
|
+ uh += ch + ih;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cx = m->wx + ov + uw;
|
||||||
|
+ cw = (m->ww - 2*ov - uw) / (cols - ci);
|
||||||
|
+ uw += cw + iv;
|
||||||
|
+
|
||||||
|
+ resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Default tile layout + gaps
|
||||||
|
+ */
|
||||||
|
+static void
|
||||||
|
+tile(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ unsigned int i, n;
|
||||||
|
+ int oh, ov, ih, iv;
|
||||||
|
+ int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
+ int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
+ float mfacts, sfacts;
|
||||||
|
+ int mrest, srest;
|
||||||
|
+ Client *c;
|
||||||
|
+
|
||||||
|
+ getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
+ if (n == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ sx = mx = m->wx + ov;
|
||||||
|
+ sy = my = m->wy + oh;
|
||||||
|
+ mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
|
||||||
|
+ sh = m->wh - 2*oh - ih * (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 - sw;
|
||||||
|
+ sx = mx + mw + iv;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
+
|
||||||
|
+ 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 / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ my += HEIGHT(c) + ih;
|
||||||
|
+ } else {
|
||||||
|
+ resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
+ sy += HEIGHT(c) + ih;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
\ No newline at end of file
|
||||||
|
--
|
||||||
|
2.19.1
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 4465af1..c4aa3de 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -416,7 +416,7 @@ attachstack(Client *c)
|
||||||
|
void
|
||||||
|
buttonpress(XEvent *e)
|
||||||
|
{
|
||||||
|
- unsigned int i, x, click;
|
||||||
|
+ unsigned int i, x, click, occ = 0;
|
||||||
|
Arg arg = {0};
|
||||||
|
Client *c;
|
||||||
|
Monitor *m;
|
||||||
|
@@ -431,9 +431,14 @@ buttonpress(XEvent *e)
|
||||||
|
}
|
||||||
|
if (ev->window == selmon->barwin) {
|
||||||
|
i = x = 0;
|
||||||
|
- do
|
||||||
|
+ for (c = m->clients; c; c = c->next)
|
||||||
|
+ occ |= c->tags == 255 ? 0 : c->tags;
|
||||||
|
+ do {
|
||||||
|
+ /* do not reserve space for vacant tags */
|
||||||
|
+ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
|
||||||
|
+ continue;
|
||||||
|
x += TEXTW(tags[i]);
|
||||||
|
- while (ev->x >= x && ++i < LENGTH(tags));
|
||||||
|
+ } while (ev->x >= x && ++i < LENGTH(tags));
|
||||||
|
if (i < LENGTH(tags)) {
|
||||||
|
click = ClkTagBar;
|
||||||
|
arg.ui = 1 << i;
|
||||||
|
@@ -709,19 +714,19 @@ drawbar(Monitor *m)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (c = m->clients; c; c = c->next) {
|
||||||
|
- occ |= c->tags;
|
||||||
|
+ occ |= c->tags == 255 ? 0 : c->tags;
|
||||||
|
if (c->isurgent)
|
||||||
|
urg |= c->tags;
|
||||||
|
}
|
||||||
|
x = 0;
|
||||||
|
for (i = 0; i < LENGTH(tags); i++) {
|
||||||
|
+ /* do not draw vacant tags */
|
||||||
|
+ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
w = TEXTW(tags[i]);
|
||||||
|
drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
|
||||||
|
drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
|
||||||
|
- if (occ & 1 << i)
|
||||||
|
- drw_rect(drw, x + boxs, boxs, boxw, boxw,
|
||||||
|
- m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
|
||||||
|
- urg & 1 << i);
|
||||||
|
x += w;
|
||||||
|
}
|
||||||
|
w = blw = TEXTW(m->ltsymbol);
|
|
@ -0,0 +1,64 @@
|
||||||
|
diff -u dwm/config.def.h dwmnew/config.def.h
|
||||||
|
--- dwm/config.def.h 2020-03-01 19:10:06.676821764 +1300
|
||||||
|
+++ dwmnew/config.def.h 2020-03-01 19:29:26.276901430 +1300
|
||||||
|
@@ -26,9 +26,9 @@
|
||||||
|
* WM_CLASS(STRING) = instance, class
|
||||||
|
* WM_NAME(STRING) = title
|
||||||
|
*/
|
||||||
|
- /* class instance title tags mask isfloating monitor */
|
||||||
|
- { "Gimp", NULL, NULL, 0, 1, -1 },
|
||||||
|
- { "Firefox", NULL, NULL, 1 << 8, 0, -1 },
|
||||||
|
+ /* class instance title tags mask isfloating monitor float x,y,w,h floatborderpx*/
|
||||||
|
+ { "Gimp", NULL, NULL, 0, 1, -1, 50,50,500,500, 5 },
|
||||||
|
+ { "Firefox", NULL, NULL, 1 << 8, 0, -1, 50,50,500,500, 5 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* layout(s) */
|
||||||
|
Only in dwmnew: config.h
|
||||||
|
Only in dwmnew: drw.o
|
||||||
|
diff -u dwm/dwm.c dwmnew/dwm.c
|
||||||
|
--- dwm/dwm.c 2020-03-01 19:10:06.680155097 +1300
|
||||||
|
+++ dwmnew/dwm.c 2020-03-01 19:28:26.793564016 +1300
|
||||||
|
@@ -93,6 +93,7 @@
|
||||||
|
int bw, oldbw;
|
||||||
|
unsigned int tags;
|
||||||
|
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
|
||||||
|
+ int floatborderpx;
|
||||||
|
Client *next;
|
||||||
|
Client *snext;
|
||||||
|
Monitor *mon;
|
||||||
|
@@ -139,6 +140,8 @@
|
||||||
|
unsigned int tags;
|
||||||
|
int isfloating;
|
||||||
|
int monitor;
|
||||||
|
+ int floatx, floaty, floatw, floath;
|
||||||
|
+ int floatborderpx;
|
||||||
|
} Rule;
|
||||||
|
|
||||||
|
/* function declarations */
|
||||||
|
@@ -299,6 +302,13 @@
|
||||||
|
{
|
||||||
|
c->isfloating = r->isfloating;
|
||||||
|
c->tags |= r->tags;
|
||||||
|
+ c->floatborderpx = r->floatborderpx;
|
||||||
|
+ if (r->isfloating) {
|
||||||
|
+ c->x = r->floatx;
|
||||||
|
+ c->y = r->floaty;
|
||||||
|
+ c->w = r->floatw;
|
||||||
|
+ c->h = r->floath;
|
||||||
|
+ }
|
||||||
|
for (m = mons; m && m->num != r->monitor; m = m->next);
|
||||||
|
if (m)
|
||||||
|
c->mon = m;
|
||||||
|
@@ -1281,7 +1291,10 @@
|
||||||
|
c->oldy = c->y; c->y = wc.y = y;
|
||||||
|
c->oldw = c->w; c->w = wc.width = w;
|
||||||
|
c->oldh = c->h; c->h = wc.height = h;
|
||||||
|
- wc.border_width = c->bw;
|
||||||
|
+ if (c->isfloating)
|
||||||
|
+ wc.border_width = c->floatborderpx;
|
||||||
|
+ else
|
||||||
|
+ wc.border_width = c->bw;
|
||||||
|
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
|
||||||
|
configure(c);
|
||||||
|
XSync(dpy, False);
|
|
@ -0,0 +1,177 @@
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 4465af1..6474055 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -111,6 +111,7 @@ typedef struct {
|
||||||
|
void (*arrange)(Monitor *);
|
||||||
|
} Layout;
|
||||||
|
|
||||||
|
+typedef struct Pertag Pertag;
|
||||||
|
struct Monitor {
|
||||||
|
char ltsymbol[16];
|
||||||
|
float mfact;
|
||||||
|
@@ -130,6 +131,7 @@ struct Monitor {
|
||||||
|
Monitor *next;
|
||||||
|
Window barwin;
|
||||||
|
const Layout *lt[2];
|
||||||
|
+ Pertag *pertag;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
@@ -271,6 +273,15 @@ static Window root, wmcheckwin;
|
||||||
|
/* configuration, allows nested code to access above variables */
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
+struct Pertag {
|
||||||
|
+ unsigned int curtag, prevtag; /* current and previous tag */
|
||||||
|
+ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */
|
||||||
|
+ float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */
|
||||||
|
+ unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */
|
||||||
|
+ const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layouts indexes */
|
||||||
|
+ int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
/* compile-time check if all tags fit into an unsigned int bit array. */
|
||||||
|
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
|
||||||
|
|
||||||
|
@@ -631,6 +642,7 @@ Monitor *
|
||||||
|
createmon(void)
|
||||||
|
{
|
||||||
|
Monitor *m;
|
||||||
|
+ unsigned int i;
|
||||||
|
|
||||||
|
m = ecalloc(1, sizeof(Monitor));
|
||||||
|
m->tagset[0] = m->tagset[1] = 1;
|
||||||
|
@@ -641,6 +653,20 @@ createmon(void)
|
||||||
|
m->lt[0] = &layouts[0];
|
||||||
|
m->lt[1] = &layouts[1 % LENGTH(layouts)];
|
||||||
|
strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
|
||||||
|
+ m->pertag = ecalloc(1, sizeof(Pertag));
|
||||||
|
+ m->pertag->curtag = m->pertag->prevtag = 1;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i <= LENGTH(tags); i++) {
|
||||||
|
+ m->pertag->nmasters[i] = m->nmaster;
|
||||||
|
+ m->pertag->mfacts[i] = m->mfact;
|
||||||
|
+
|
||||||
|
+ m->pertag->ltidxs[i][0] = m->lt[0];
|
||||||
|
+ m->pertag->ltidxs[i][1] = m->lt[1];
|
||||||
|
+ m->pertag->sellts[i] = m->sellt;
|
||||||
|
+
|
||||||
|
+ m->pertag->showbars[i] = m->showbar;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -966,7 +992,7 @@ grabkeys(void)
|
||||||
|
void
|
||||||
|
incnmaster(const Arg *arg)
|
||||||
|
{
|
||||||
|
- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
|
||||||
|
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0);
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1501,9 +1527,9 @@ void
|
||||||
|
setlayout(const Arg *arg)
|
||||||
|
{
|
||||||
|
if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
|
||||||
|
- selmon->sellt ^= 1;
|
||||||
|
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
|
||||||
|
if (arg && arg->v)
|
||||||
|
- selmon->lt[selmon->sellt] = (Layout *)arg->v;
|
||||||
|
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
|
||||||
|
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
|
||||||
|
if (selmon->sel)
|
||||||
|
arrange(selmon);
|
||||||
|
@@ -1522,7 +1548,7 @@ setmfact(const Arg *arg)
|
||||||
|
f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
|
||||||
|
if (f < 0.1 || f > 0.9)
|
||||||
|
return;
|
||||||
|
- selmon->mfact = f;
|
||||||
|
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1699,7 +1725,7 @@ tile(Monitor *m)
|
||||||
|
void
|
||||||
|
togglebar(const Arg *arg)
|
||||||
|
{
|
||||||
|
- selmon->showbar = !selmon->showbar;
|
||||||
|
+ selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
|
||||||
|
updatebarpos(selmon);
|
||||||
|
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
|
||||||
|
arrange(selmon);
|
||||||
|
@@ -1738,9 +1764,33 @@ void
|
||||||
|
toggleview(const Arg *arg)
|
||||||
|
{
|
||||||
|
unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
|
||||||
|
+ int i;
|
||||||
|
|
||||||
|
if (newtagset) {
|
||||||
|
selmon->tagset[selmon->seltags] = newtagset;
|
||||||
|
+
|
||||||
|
+ if (newtagset == ~0) {
|
||||||
|
+ selmon->pertag->prevtag = selmon->pertag->curtag;
|
||||||
|
+ selmon->pertag->curtag = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* test if the user did not select the same tag */
|
||||||
|
+ if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
|
||||||
|
+ selmon->pertag->prevtag = selmon->pertag->curtag;
|
||||||
|
+ for (i = 0; !(newtagset & 1 << i); i++) ;
|
||||||
|
+ selmon->pertag->curtag = i + 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* apply settings for this view */
|
||||||
|
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
|
||||||
|
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
|
||||||
|
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
|
||||||
|
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
|
||||||
|
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
|
||||||
|
+
|
||||||
|
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
|
||||||
|
+ togglebar(NULL);
|
||||||
|
+
|
||||||
|
focus(NULL);
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
@@ -2035,11 +2085,37 @@ updatewmhints(Client *c)
|
||||||
|
void
|
||||||
|
view(const Arg *arg)
|
||||||
|
{
|
||||||
|
+ int i;
|
||||||
|
+ unsigned int tmptag;
|
||||||
|
+
|
||||||
|
if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
|
||||||
|
return;
|
||||||
|
selmon->seltags ^= 1; /* toggle sel tagset */
|
||||||
|
- if (arg->ui & TAGMASK)
|
||||||
|
+ if (arg->ui & TAGMASK) {
|
||||||
|
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
|
||||||
|
+ selmon->pertag->prevtag = selmon->pertag->curtag;
|
||||||
|
+
|
||||||
|
+ if (arg->ui == ~0)
|
||||||
|
+ selmon->pertag->curtag = 0;
|
||||||
|
+ else {
|
||||||
|
+ for (i = 0; !(arg->ui & 1 << i); i++) ;
|
||||||
|
+ selmon->pertag->curtag = i + 1;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ tmptag = selmon->pertag->prevtag;
|
||||||
|
+ selmon->pertag->prevtag = selmon->pertag->curtag;
|
||||||
|
+ selmon->pertag->curtag = tmptag;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
|
||||||
|
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
|
||||||
|
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
|
||||||
|
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
|
||||||
|
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
|
||||||
|
+
|
||||||
|
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
|
||||||
|
+ togglebar(NULL);
|
||||||
|
+
|
||||||
|
focus(NULL);
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
From 1004b9406e4b89448cf9d3b18955dbd0d55a571d Mon Sep 17 00:00:00 2001
|
||||||
|
From: bakkeby <bakkeby@gmail.com>
|
||||||
|
Date: Wed, 1 Jul 2020 08:05:35 +0200
|
||||||
|
Subject: [PATCH] holdbar: variant of the patch where holdbar is only active
|
||||||
|
when the bar is toggled off
|
||||||
|
|
||||||
|
Additionally this allows the use of the primary MOD key to be used as the holdbar key while
|
||||||
|
still allowing the bar to be toggled on and off using MOD+b. This gives a more intuitive and
|
||||||
|
flexible feel when using this functionality.
|
||||||
|
|
||||||
|
Use xev to find the keysym for the key that you want to use and add/update the HOLDKEY
|
||||||
|
definition in config.h.
|
||||||
|
|
||||||
|
E.g. using Alt_L as the HOLDKEY
|
||||||
|
---
|
||||||
|
config.def.h | 2 ++
|
||||||
|
dwm.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
2 files changed, 52 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..8611189 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -50,6 +50,7 @@ static const Layout layouts[] = {
|
||||||
|
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||||
|
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
|
||||||
|
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
|
||||||
|
+#define HOLDKEY 0 // replace 0 with the keysym to activate holdbar
|
||||||
|
|
||||||
|
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
||||||
|
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||||
|
@@ -94,6 +95,7 @@ static Key keys[] = {
|
||||||
|
TAGKEYS( XK_8, 7)
|
||||||
|
TAGKEYS( XK_9, 8)
|
||||||
|
{ MODKEY|ShiftMask, XK_q, quit, {0} },
|
||||||
|
+ { 0, HOLDKEY, holdbar, {0} },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* button definitions */
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 4465af1..def5f66 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -176,6 +176,7 @@ static void grabbuttons(Client *c, int focused);
|
||||||
|
static void grabkeys(void);
|
||||||
|
static void incnmaster(const Arg *arg);
|
||||||
|
static void keypress(XEvent *e);
|
||||||
|
+static void keyrelease(XEvent *e);
|
||||||
|
static void killclient(const Arg *arg);
|
||||||
|
static void manage(Window w, XWindowAttributes *wa);
|
||||||
|
static void mappingnotify(XEvent *e);
|
||||||
|
@@ -210,6 +211,7 @@ static void tag(const Arg *arg);
|
||||||
|
static void tagmon(const Arg *arg);
|
||||||
|
static void tile(Monitor *);
|
||||||
|
static void togglebar(const Arg *arg);
|
||||||
|
+static void holdbar(const Arg *arg);
|
||||||
|
static void togglefloating(const Arg *arg);
|
||||||
|
static void toggletag(const Arg *arg);
|
||||||
|
static void toggleview(const Arg *arg);
|
||||||
|
@@ -217,6 +219,7 @@ static void unfocus(Client *c, int setfocus);
|
||||||
|
static void unmanage(Client *c, int destroyed);
|
||||||
|
static void unmapnotify(XEvent *e);
|
||||||
|
static void updatebarpos(Monitor *m);
|
||||||
|
+static void updateholdbarpos(Monitor *m);
|
||||||
|
static void updatebars(void);
|
||||||
|
static void updateclientlist(void);
|
||||||
|
static int updategeom(void);
|
||||||
|
@@ -245,6 +248,7 @@ static int (*xerrorxlib)(Display *, XErrorEvent *);
|
||||||
|
static unsigned int numlockmask = 0;
|
||||||
|
static void (*handler[LASTEvent]) (XEvent *) = {
|
||||||
|
[ButtonPress] = buttonpress,
|
||||||
|
+ [ButtonRelease] = keyrelease,
|
||||||
|
[ClientMessage] = clientmessage,
|
||||||
|
[ConfigureRequest] = configurerequest,
|
||||||
|
[ConfigureNotify] = configurenotify,
|
||||||
|
@@ -252,6 +256,7 @@ static void (*handler[LASTEvent]) (XEvent *) = {
|
||||||
|
[EnterNotify] = enternotify,
|
||||||
|
[Expose] = expose,
|
||||||
|
[FocusIn] = focusin,
|
||||||
|
+ [KeyRelease] = keyrelease,
|
||||||
|
[KeyPress] = keypress,
|
||||||
|
[MappingNotify] = mappingnotify,
|
||||||
|
[MapRequest] = maprequest,
|
||||||
|
@@ -275,6 +280,50 @@ static Window root, wmcheckwin;
|
||||||
|
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
|
||||||
|
|
||||||
|
/* function implementations */
|
||||||
|
+void
|
||||||
|
+holdbar(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ if (selmon->showbar)
|
||||||
|
+ return;
|
||||||
|
+ selmon->showbar = 2;
|
||||||
|
+ updateholdbarpos(selmon);
|
||||||
|
+ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+keyrelease(XEvent *e)
|
||||||
|
+{
|
||||||
|
+ if (XEventsQueued(dpy, QueuedAfterReading)) {
|
||||||
|
+ XEvent ne;
|
||||||
|
+ XPeekEvent(dpy, &ne);
|
||||||
|
+
|
||||||
|
+ if (ne.type == KeyPress && ne.xkey.time == e->xkey.time &&
|
||||||
|
+ ne.xkey.keycode == e->xkey.keycode) {
|
||||||
|
+ XNextEvent(dpy, &ne);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ if (e->xkey.keycode == XKeysymToKeycode(dpy, HOLDKEY) && selmon->showbar == 2) {
|
||||||
|
+ selmon->showbar = 0;
|
||||||
|
+ updateholdbarpos(selmon);
|
||||||
|
+ XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
|
||||||
|
+ arrange(selmon);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+updateholdbarpos(Monitor *m)
|
||||||
|
+{
|
||||||
|
+ m->wy = m->my;
|
||||||
|
+ m->wh = m->mh;
|
||||||
|
+ if (m->showbar) {
|
||||||
|
+ m->by = m->topbar ? m->wy : m->wy + m->wh - bh;
|
||||||
|
+ m->wy = m->topbar ? m->wy - bh + bh : m->wy;
|
||||||
|
+ } else {
|
||||||
|
+ m->by = -bh;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
applyrules(Client *c)
|
||||||
|
{
|
||||||
|
@@ -1699,7 +1748,7 @@ tile(Monitor *m)
|
||||||
|
void
|
||||||
|
togglebar(const Arg *arg)
|
||||||
|
{
|
||||||
|
- selmon->showbar = !selmon->showbar;
|
||||||
|
+ selmon->showbar = (selmon->showbar == 2 ? 1 : !selmon->showbar);
|
||||||
|
updatebarpos(selmon);
|
||||||
|
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
|
||||||
|
arrange(selmon);
|
||||||
|
--
|
||||||
|
2.19.1
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
From f20e5593e154e7e46c3f7100bd1378c7844b5ec8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dirk Leichsenring <dlei@reddott.de>
|
||||||
|
Date: Sun, 21 Jun 2020 14:00:40 +0200
|
||||||
|
Subject: [PATCH] Make the borders of urgent windows a different color - for dwm 6.2
|
||||||
|
|
||||||
|
---
|
||||||
|
config.def.h | 2 ++
|
||||||
|
dwm.c | 7 +++++--
|
||||||
|
2 files changed, 7 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..1cb4492 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -12,10 +12,12 @@ static const char col_gray2[] = "#444444";
|
||||||
|
static const char col_gray3[] = "#bbbbbb";
|
||||||
|
static const char col_gray4[] = "#eeeeee";
|
||||||
|
static const char col_cyan[] = "#005577";
|
||||||
|
+static const char col_urgborder[] = "#ff0000";
|
||||||
|
static const char *colors[][3] = {
|
||||||
|
/* fg bg border */
|
||||||
|
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
|
||||||
|
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
|
||||||
|
+ [SchemeUrg] = { col_gray4, col_cyan, col_urgborder },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* tagging */
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 4465af1..fda4013 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -59,7 +59,7 @@
|
||||||
|
|
||||||
|
/* enums */
|
||||||
|
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
|
||||||
|
-enum { SchemeNorm, SchemeSel }; /* color schemes */
|
||||||
|
+enum { SchemeNorm, SchemeSel, SchemeUrg }; /* color schemes */
|
||||||
|
enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
|
||||||
|
NetWMFullscreen, NetActiveWindow, NetWMWindowType,
|
||||||
|
NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
|
||||||
|
@@ -2022,8 +2022,11 @@ updatewmhints(Client *c)
|
||||||
|
if (c == selmon->sel && wmh->flags & XUrgencyHint) {
|
||||||
|
wmh->flags &= ~XUrgencyHint;
|
||||||
|
XSetWMHints(dpy, c->win, wmh);
|
||||||
|
- } else
|
||||||
|
+ } else {
|
||||||
|
c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0;
|
||||||
|
+ if (c->isurgent)
|
||||||
|
+ XSetWindowBorder(dpy, c->win, scheme[SchemeUrg][ColBorder].pixel);
|
||||||
|
+ }
|
||||||
|
if (wmh->flags & InputHint)
|
||||||
|
c->neverfocus = !wmh->input;
|
||||||
|
else
|
||||||
|
--
|
||||||
|
2.27.0
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 1c0b587..b67825e 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -103,7 +103,9 @@ static Button buttons[] = {
|
||||||
|
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
|
||||||
|
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
|
||||||
|
{ ClkWinTitle, 0, Button2, zoom, {0} },
|
||||||
|
- { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
|
||||||
|
+ { ClkStatusText, 0, Button1, sigdwmblocks, {.i = 1} },
|
||||||
|
+ { ClkStatusText, 0, Button2, sigdwmblocks, {.i = 2} },
|
||||||
|
+ { ClkStatusText, 0, Button3, sigdwmblocks, {.i = 3} },
|
||||||
|
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
|
||||||
|
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
|
||||||
|
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
|
||||||
|
diff --git a/dwm.c b/dwm.c
|
||||||
|
index 4465af1..c600131 100644
|
||||||
|
--- a/dwm.c
|
||||||
|
+++ b/dwm.c
|
||||||
|
@@ -156,6 +156,7 @@ static void clientmessage(XEvent *e);
|
||||||
|
static void configure(Client *c);
|
||||||
|
static void configurenotify(XEvent *e);
|
||||||
|
static void configurerequest(XEvent *e);
|
||||||
|
+static void copyvalidchars(char *text, char *rawtext);
|
||||||
|
static Monitor *createmon(void);
|
||||||
|
static void destroynotify(XEvent *e);
|
||||||
|
static void detach(Client *c);
|
||||||
|
@@ -169,6 +170,7 @@ static void focus(Client *c);
|
||||||
|
static void focusin(XEvent *e);
|
||||||
|
static void focusmon(const Arg *arg);
|
||||||
|
static void focusstack(const Arg *arg);
|
||||||
|
+static int getdwmblockspid();
|
||||||
|
static int getrootptr(int *x, int *y);
|
||||||
|
static long getstate(Window w);
|
||||||
|
static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
|
||||||
|
@@ -205,6 +207,7 @@ static void setup(void);
|
||||||
|
static void seturgent(Client *c, int urg);
|
||||||
|
static void showhide(Client *c);
|
||||||
|
static void sigchld(int unused);
|
||||||
|
+static void sigdwmblocks(const Arg *arg);
|
||||||
|
static void spawn(const Arg *arg);
|
||||||
|
static void tag(const Arg *arg);
|
||||||
|
static void tagmon(const Arg *arg);
|
||||||
|
@@ -237,6 +240,9 @@ static void zoom(const Arg *arg);
|
||||||
|
/* variables */
|
||||||
|
static const char broken[] = "broken";
|
||||||
|
static char stext[256];
|
||||||
|
+static char rawstext[256];
|
||||||
|
+static int dwmblockssig;
|
||||||
|
+pid_t dwmblockspid = 0;
|
||||||
|
static int screen;
|
||||||
|
static int sw, sh; /* X display screen geometry width, height */
|
||||||
|
static int bh, blw = 0; /* bar geometry */
|
||||||
|
@@ -439,9 +445,26 @@ buttonpress(XEvent *e)
|
||||||
|
arg.ui = 1 << i;
|
||||||
|
} else if (ev->x < x + blw)
|
||||||
|
click = ClkLtSymbol;
|
||||||
|
- else if (ev->x > selmon->ww - TEXTW(stext))
|
||||||
|
+ else if (ev->x > (x = selmon->ww - TEXTW(stext) + lrpad)) {
|
||||||
|
click = ClkStatusText;
|
||||||
|
- else
|
||||||
|
+
|
||||||
|
+ char *text = rawstext;
|
||||||
|
+ int i = -1;
|
||||||
|
+ char ch;
|
||||||
|
+ dwmblockssig = 0;
|
||||||
|
+ while (text[++i]) {
|
||||||
|
+ if ((unsigned char)text[i] < ' ') {
|
||||||
|
+ ch = text[i];
|
||||||
|
+ text[i] = '\0';
|
||||||
|
+ x += TEXTW(text) - lrpad;
|
||||||
|
+ text[i] = ch;
|
||||||
|
+ text += i+1;
|
||||||
|
+ i = -1;
|
||||||
|
+ if (x >= ev->x) break;
|
||||||
|
+ dwmblockssig = ch;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ } else
|
||||||
|
click = ClkWinTitle;
|
||||||
|
} else if ((c = wintoclient(ev->window))) {
|
||||||
|
focus(c);
|
||||||
|
@@ -627,6 +650,19 @@ configurerequest(XEvent *e)
|
||||||
|
XSync(dpy, False);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+copyvalidchars(char *text, char *rawtext)
|
||||||
|
+{
|
||||||
|
+ int i = -1, j = 0;
|
||||||
|
+
|
||||||
|
+ while(rawtext[++i]) {
|
||||||
|
+ if ((unsigned char)rawtext[i] >= ' ') {
|
||||||
|
+ text[j++] = rawtext[i];
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ text[j] = '\0';
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
Monitor *
|
||||||
|
createmon(void)
|
||||||
|
{
|
||||||
|
@@ -871,6 +907,18 @@ getatomprop(Client *c, Atom prop)
|
||||||
|
return atom;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int
|
||||||
|
+getdwmblockspid()
|
||||||
|
+{
|
||||||
|
+ char buf[16];
|
||||||
|
+ FILE *fp = popen("pidof -s dwmblocks", "r");
|
||||||
|
+ fgets(buf, sizeof(buf), fp);
|
||||||
|
+ pid_t pid = strtoul(buf, NULL, 10);
|
||||||
|
+ pclose(fp);
|
||||||
|
+ dwmblockspid = pid;
|
||||||
|
+ return pid != 0 ? 0 : -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int
|
||||||
|
getrootptr(int *x, int *y)
|
||||||
|
{
|
||||||
|
@@ -1636,6 +1684,23 @@ sigchld(int unused)
|
||||||
|
while (0 < waitpid(-1, NULL, WNOHANG));
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+sigdwmblocks(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ union sigval sv;
|
||||||
|
+ sv.sival_int = (dwmblockssig << 8) | arg->i;
|
||||||
|
+ if (!dwmblockspid)
|
||||||
|
+ if (getdwmblockspid() == -1)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (sigqueue(dwmblockspid, SIGUSR1, sv) == -1) {
|
||||||
|
+ if (errno == ESRCH) {
|
||||||
|
+ if (!getdwmblockspid())
|
||||||
|
+ sigqueue(dwmblockspid, SIGUSR1, sv);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
spawn(const Arg *arg)
|
||||||
|
{
|
||||||
|
@@ -1987,8 +2052,10 @@ updatesizehints(Client *c)
|
||||||
|
void
|
||||||
|
updatestatus(void)
|
||||||
|
{
|
||||||
|
- if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
|
||||||
|
+ if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext)))
|
||||||
|
strcpy(stext, "dwm-"VERSION);
|
||||||
|
+ else
|
||||||
|
+ copyvalidchars(stext, rawstext);
|
||||||
|
drawbar(selmon);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,809 @@
|
||||||
|
/* 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);
|
||||||
|
/* Layouts (delete the ones you do not need) */
|
||||||
|
static void bstack(Monitor *m);
|
||||||
|
static void bstackhoriz(Monitor *m);
|
||||||
|
static void centeredmaster(Monitor *m);
|
||||||
|
static void centeredfloatingmaster(Monitor *m);
|
||||||
|
static void deck(Monitor *m);
|
||||||
|
static void dwindle(Monitor *m);
|
||||||
|
static void fibonacci(Monitor *m, int s);
|
||||||
|
static void grid(Monitor *m);
|
||||||
|
static void nrowgrid(Monitor *m);
|
||||||
|
static void spiral(Monitor *m);
|
||||||
|
static void tile(Monitor *m);
|
||||||
|
/* Internals */
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* Settings */
|
||||||
|
#if !PERTAG_PATCH
|
||||||
|
static int enablegaps = 1;
|
||||||
|
#endif // PERTAG_PATCH
|
||||||
|
|
||||||
|
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
|
||||||
|
togglegaps(const Arg *arg)
|
||||||
|
{
|
||||||
|
#if PERTAG_PATCH
|
||||||
|
selmon->pertag->enablegaps[selmon->pertag->curtag] = !selmon->pertag->enablegaps[selmon->pertag->curtag];
|
||||||
|
#else
|
||||||
|
enablegaps = !enablegaps;
|
||||||
|
#endif // PERTAG_PATCH
|
||||||
|
arrange(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
#if PERTAG_PATCH
|
||||||
|
oe = ie = selmon->pertag->enablegaps[selmon->pertag->curtag];
|
||||||
|
#else
|
||||||
|
oe = ie = enablegaps;
|
||||||
|
#endif // PERTAG_PATCH
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
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, sfacts;
|
||||||
|
int mtotal = 0, stotal = 0;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
|
||||||
|
mfacts = MIN(n, m->nmaster);
|
||||||
|
sfacts = n - m->nmaster;
|
||||||
|
|
||||||
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
|
||||||
|
if (n < m->nmaster)
|
||||||
|
mtotal += msize / mfacts;
|
||||||
|
else
|
||||||
|
stotal += ssize / sfacts;
|
||||||
|
|
||||||
|
*mf = mfacts; // total factor of master area
|
||||||
|
*sf = sfacts; // total factor of stack area
|
||||||
|
*mr = msize - mtotal; // the remainder (rest) of pixels after an even master split
|
||||||
|
*sr = ssize - stotal; // the remainder (rest) of pixels after an even stack split
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Layouts
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bottomstack layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/bottomstack/
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
bstack(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
float mfacts, sfacts;
|
||||||
|
int mrest, srest;
|
||||||
|
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;
|
||||||
|
mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
|
||||||
|
sw = m->ww - 2*ov - iv * (n - m->nmaster - 1);
|
||||||
|
|
||||||
|
if (m->nmaster && n > m->nmaster) {
|
||||||
|
sh = (mh - ih) * (1 - m->mfact);
|
||||||
|
mh = mh - ih - sh;
|
||||||
|
sx = mx;
|
||||||
|
sy = my + mh + ih;
|
||||||
|
}
|
||||||
|
|
||||||
|
getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
if (i < m->nmaster) {
|
||||||
|
resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
mx += WIDTH(c) + iv;
|
||||||
|
} else {
|
||||||
|
resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
sx += WIDTH(c) + iv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bstackhoriz(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
float mfacts, sfacts;
|
||||||
|
int mrest, srest;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sx = mx = m->wx + ov;
|
||||||
|
sy = my = m->wy + oh;
|
||||||
|
mh = m->wh - 2*oh;
|
||||||
|
sh = m->wh - 2*oh - ih * (n - m->nmaster - 1);
|
||||||
|
mw = m->ww - 2*ov - iv * (MIN(n, m->nmaster) - 1);
|
||||||
|
sw = m->ww - 2*ov;
|
||||||
|
|
||||||
|
if (m->nmaster && n > m->nmaster) {
|
||||||
|
sh = (mh - ih) * (1 - m->mfact);
|
||||||
|
mh = mh - ih - sh;
|
||||||
|
sy = my + mh + ih;
|
||||||
|
sh = m->wh - mh - 2*oh - ih * (n - m->nmaster);
|
||||||
|
}
|
||||||
|
|
||||||
|
getfacts(m, mw, sh, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
if (i < m->nmaster) {
|
||||||
|
resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
mx += WIDTH(c) + iv;
|
||||||
|
} else {
|
||||||
|
resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
sy += HEIGHT(c) + ih;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Centred master layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/centeredmaster/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
centeredmaster(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int lx = 0, ly = 0, lw = 0, lh = 0;
|
||||||
|
int rx = 0, ry = 0, rw = 0, rh = 0;
|
||||||
|
float mfacts = 0, lfacts = 0, rfacts = 0;
|
||||||
|
int mtotal = 0, ltotal = 0, rtotal = 0;
|
||||||
|
int mrest = 0, lrest = 0, rrest = 0;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* initialize areas */
|
||||||
|
mx = m->wx + ov;
|
||||||
|
my = m->wy + oh;
|
||||||
|
mh = m->wh - 2*oh - ih * ((!m->nmaster ? n : MIN(n, m->nmaster)) - 1);
|
||||||
|
mw = m->ww - 2*ov;
|
||||||
|
lh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - 1);
|
||||||
|
rh = m->wh - 2*oh - ih * (((n - m->nmaster) / 2) - ((n - m->nmaster) % 2 ? 0 : 1));
|
||||||
|
|
||||||
|
if (m->nmaster && n > m->nmaster) {
|
||||||
|
/* go mfact box in the center if more than nmaster clients */
|
||||||
|
if (n - m->nmaster > 1) {
|
||||||
|
/* ||<-S->|<---M--->|<-S->|| */
|
||||||
|
mw = (m->ww - 2*ov - 2*iv) * m->mfact;
|
||||||
|
lw = (m->ww - mw - 2*ov - 2*iv) / 2;
|
||||||
|
rw = (m->ww - mw - 2*ov - 2*iv) - lw;
|
||||||
|
mx += lw + iv;
|
||||||
|
} else {
|
||||||
|
/* ||<---M--->|<-S->|| */
|
||||||
|
mw = (mw - iv) * m->mfact;
|
||||||
|
lw = 0;
|
||||||
|
rw = m->ww - mw - iv - 2*ov;
|
||||||
|
}
|
||||||
|
lx = m->wx + ov;
|
||||||
|
ly = m->wy + oh;
|
||||||
|
rx = mx + mw + iv;
|
||||||
|
ry = m->wy + oh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate facts */
|
||||||
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
|
||||||
|
if (!m->nmaster || n < m->nmaster)
|
||||||
|
mfacts += 1;
|
||||||
|
else if ((n - m->nmaster) % 2)
|
||||||
|
lfacts += 1; // total factor of left hand stack area
|
||||||
|
else
|
||||||
|
rfacts += 1; // total factor of right hand stack area
|
||||||
|
}
|
||||||
|
|
||||||
|
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++)
|
||||||
|
if (!m->nmaster || n < m->nmaster)
|
||||||
|
mtotal += mh / mfacts;
|
||||||
|
else if ((n - m->nmaster) % 2)
|
||||||
|
ltotal += lh / lfacts;
|
||||||
|
else
|
||||||
|
rtotal += rh / rfacts;
|
||||||
|
|
||||||
|
mrest = mh - mtotal;
|
||||||
|
lrest = lh - ltotal;
|
||||||
|
rrest = rh - rtotal;
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
if (!m->nmaster || i < m->nmaster) {
|
||||||
|
/* nmaster clients are stacked vertically, in the center of the screen */
|
||||||
|
resize(c, mx, my, mw - (2*c->bw), (mh / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
my += HEIGHT(c) + ih;
|
||||||
|
} else {
|
||||||
|
/* stack clients are stacked vertically */
|
||||||
|
if ((i - m->nmaster) % 2 ) {
|
||||||
|
resize(c, lx, ly, lw - (2*c->bw), (lh / lfacts) + ((i - 2*m->nmaster) < 2*lrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
ly += HEIGHT(c) + ih;
|
||||||
|
} else {
|
||||||
|
resize(c, rx, ry, rw - (2*c->bw), (rh / rfacts) + ((i - 2*m->nmaster) < 2*rrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
ry += HEIGHT(c) + ih;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
centeredfloatingmaster(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
float mfacts, sfacts;
|
||||||
|
float mivf = 1.0; // master inner vertical gap factor
|
||||||
|
int oh, ov, ih, iv, mrest, srest;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
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;
|
||||||
|
mw = m->ww - 2*ov - iv*(n - 1);
|
||||||
|
sw = m->ww - 2*ov - iv*(n - m->nmaster - 1);
|
||||||
|
|
||||||
|
if (m->nmaster && n > m->nmaster) {
|
||||||
|
mivf = 0.8;
|
||||||
|
/* go mfact box in the center if more than nmaster clients */
|
||||||
|
if (m->ww > m->wh) {
|
||||||
|
mw = m->ww * m->mfact - iv*mivf*(MIN(n, m->nmaster) - 1);
|
||||||
|
mh = m->wh * 0.9;
|
||||||
|
} else {
|
||||||
|
mw = m->ww * 0.9 - iv*mivf*(MIN(n, m->nmaster) - 1);
|
||||||
|
mh = m->wh * m->mfact;
|
||||||
|
}
|
||||||
|
mx = m->wx + (m->ww - mw) / 2;
|
||||||
|
my = m->wy + (m->wh - mh - 2*oh) / 2;
|
||||||
|
|
||||||
|
sx = m->wx + ov;
|
||||||
|
sy = m->wy + oh;
|
||||||
|
sh = m->wh - 2*oh;
|
||||||
|
}
|
||||||
|
|
||||||
|
getfacts(m, mw, sw, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
if (i < m->nmaster) {
|
||||||
|
/* nmaster clients are stacked horizontally, in the center of the screen */
|
||||||
|
resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
mx += WIDTH(c) + iv*mivf;
|
||||||
|
} else {
|
||||||
|
/* stack clients are stacked horizontally */
|
||||||
|
resize(c, sx, sy, (sw / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
sx += WIDTH(c) + iv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deck layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/deck/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
deck(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
float mfacts, sfacts;
|
||||||
|
int mrest, srest;
|
||||||
|
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 - sw;
|
||||||
|
sx = mx + mw + iv;
|
||||||
|
sh = m->wh - 2*oh;
|
||||||
|
}
|
||||||
|
|
||||||
|
getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
|
||||||
|
if (n - m->nmaster > 0) /* override layout symbol */
|
||||||
|
snprintf(m->ltsymbol, sizeof m->ltsymbol, "D %d", n - m->nmaster);
|
||||||
|
|
||||||
|
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 / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
my += HEIGHT(c) + ih;
|
||||||
|
} else {
|
||||||
|
resize(c, sx, sy, sw - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fibonacci layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/fibonacci/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fibonacci(Monitor *m, int s)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int nx, ny, nw, nh;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int nv, hrest = 0, wrest = 0, r = 1;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
nx = m->wx + ov;
|
||||||
|
ny = m->wy + oh;
|
||||||
|
nw = m->ww - 2*ov;
|
||||||
|
nh = m->wh - 2*oh;
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
|
||||||
|
if (r) {
|
||||||
|
if ((i % 2 && (nh - ih) / 2 <= (bh + 2*c->bw))
|
||||||
|
|| (!(i % 2) && (nw - iv) / 2 <= (bh + 2*c->bw))) {
|
||||||
|
r = 0;
|
||||||
|
}
|
||||||
|
if (r && i < n - 1) {
|
||||||
|
if (i % 2) {
|
||||||
|
nv = (nh - ih) / 2;
|
||||||
|
hrest = nh - 2*nv - ih;
|
||||||
|
nh = nv;
|
||||||
|
} else {
|
||||||
|
nv = (nw - iv) / 2;
|
||||||
|
wrest = nw - 2*nv - iv;
|
||||||
|
nw = nv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((i % 4) == 2 && !s)
|
||||||
|
nx += nw + iv;
|
||||||
|
else if ((i % 4) == 3 && !s)
|
||||||
|
ny += nh + ih;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((i % 4) == 0) {
|
||||||
|
if (s) {
|
||||||
|
ny += nh + ih;
|
||||||
|
nh += hrest;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nh -= hrest;
|
||||||
|
ny -= nh + ih;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((i % 4) == 1) {
|
||||||
|
nx += nw + iv;
|
||||||
|
nw += wrest;
|
||||||
|
}
|
||||||
|
else if ((i % 4) == 2) {
|
||||||
|
ny += nh + ih;
|
||||||
|
nh += hrest;
|
||||||
|
if (i < n - 1)
|
||||||
|
nw += wrest;
|
||||||
|
}
|
||||||
|
else if ((i % 4) == 3) {
|
||||||
|
if (s) {
|
||||||
|
nx += nw + iv;
|
||||||
|
nw -= wrest;
|
||||||
|
} else {
|
||||||
|
nw -= wrest;
|
||||||
|
nx -= nw + iv;
|
||||||
|
nh += hrest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == 0) {
|
||||||
|
if (n != 1) {
|
||||||
|
nw = (m->ww - iv - 2*ov) - (m->ww - iv - 2*ov) * (1 - m->mfact);
|
||||||
|
wrest = 0;
|
||||||
|
}
|
||||||
|
ny = m->wy + oh;
|
||||||
|
}
|
||||||
|
else if (i == 1)
|
||||||
|
nw = m->ww - nw - iv - 2*ov;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
resize(c, nx, ny, nw - (2*c->bw), nh - (2*c->bw), False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dwindle(Monitor *m)
|
||||||
|
{
|
||||||
|
fibonacci(m, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spiral(Monitor *m)
|
||||||
|
{
|
||||||
|
fibonacci(m, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gappless grid layout + gaps (ironically)
|
||||||
|
* https://dwm.suckless.org/patches/gaplessgrid/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gaplessgrid(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int x, y, cols, rows, ch, cw, cn, rn, rrest, crest; // counters
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* grid dimensions */
|
||||||
|
for (cols = 0; cols <= n/2; cols++)
|
||||||
|
if (cols*cols >= n)
|
||||||
|
break;
|
||||||
|
if (n == 5) /* set layout against the general calculation: not 1:2:2, but 2:3 */
|
||||||
|
cols = 2;
|
||||||
|
rows = n/cols;
|
||||||
|
cn = rn = 0; // reset column no, row no, client count
|
||||||
|
|
||||||
|
ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
|
||||||
|
cw = (m->ww - 2*ov - iv * (cols - 1)) / cols;
|
||||||
|
rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
|
||||||
|
crest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
|
||||||
|
x = m->wx + ov;
|
||||||
|
y = m->wy + oh;
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; i++, c = nexttiled(c->next)) {
|
||||||
|
if (i/rows + 1 > cols - n%cols) {
|
||||||
|
rows = n/cols + 1;
|
||||||
|
ch = (m->wh - 2*oh - ih * (rows - 1)) / rows;
|
||||||
|
rrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
|
||||||
|
}
|
||||||
|
resize(c,
|
||||||
|
x,
|
||||||
|
y + rn*(ch + ih) + MIN(rn, rrest),
|
||||||
|
cw + (cn < crest ? 1 : 0) - 2*c->bw,
|
||||||
|
ch + (rn < rrest ? 1 : 0) - 2*c->bw,
|
||||||
|
0);
|
||||||
|
rn++;
|
||||||
|
if (rn >= rows) {
|
||||||
|
rn = 0;
|
||||||
|
x += cw + ih + (cn < crest ? 1 : 0);
|
||||||
|
cn++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gridmode layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/gridmode/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
grid(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int cx, cy, cw, ch, cc, cr, chrest, cwrest, cols, rows;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
|
||||||
|
/* grid dimensions */
|
||||||
|
for (rows = 0; rows <= n/2; rows++)
|
||||||
|
if (rows*rows >= n)
|
||||||
|
break;
|
||||||
|
cols = (rows && (rows - 1) * rows >= n) ? rows - 1 : rows;
|
||||||
|
|
||||||
|
/* window geoms (cell height/width) */
|
||||||
|
ch = (m->wh - 2*oh - ih * (rows - 1)) / (rows ? rows : 1);
|
||||||
|
cw = (m->ww - 2*ov - iv * (cols - 1)) / (cols ? cols : 1);
|
||||||
|
chrest = (m->wh - 2*oh - ih * (rows - 1)) - ch * rows;
|
||||||
|
cwrest = (m->ww - 2*ov - iv * (cols - 1)) - cw * cols;
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) {
|
||||||
|
cc = i / rows;
|
||||||
|
cr = i % rows;
|
||||||
|
cx = m->wx + ov + cc * (cw + iv) + MIN(cc, cwrest);
|
||||||
|
cy = m->wy + oh + cr * (ch + ih) + MIN(cr, chrest);
|
||||||
|
resize(c, cx, cy, cw + (cc < cwrest ? 1 : 0) - 2*c->bw, ch + (cr < chrest ? 1 : 0) - 2*c->bw, False);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Horizontal grid layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/horizgrid/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
horizgrid(Monitor *m) {
|
||||||
|
Client *c;
|
||||||
|
unsigned int n, i;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
int ntop, nbottom = 1;
|
||||||
|
float mfacts, sfacts;
|
||||||
|
int mrest, srest;
|
||||||
|
|
||||||
|
/* Count windows */
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (n <= 2)
|
||||||
|
ntop = n;
|
||||||
|
else {
|
||||||
|
ntop = n / 2;
|
||||||
|
nbottom = n - ntop;
|
||||||
|
}
|
||||||
|
sx = mx = m->wx + ov;
|
||||||
|
sy = my = m->wy + oh;
|
||||||
|
sh = mh = m->wh - 2*oh;
|
||||||
|
sw = mw = m->ww - 2*ov;
|
||||||
|
|
||||||
|
if (n > ntop) {
|
||||||
|
sh = (mh - ih) / 2;
|
||||||
|
mh = mh - ih - sh;
|
||||||
|
sy = my + mh + ih;
|
||||||
|
mw = m->ww - 2*ov - iv * (ntop - 1);
|
||||||
|
sw = m->ww - 2*ov - iv * (nbottom - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mfacts = ntop;
|
||||||
|
sfacts = nbottom;
|
||||||
|
mrest = mw - (mw / ntop) * ntop;
|
||||||
|
srest = sw - (sw / nbottom) * nbottom;
|
||||||
|
|
||||||
|
for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
|
||||||
|
if (i < ntop) {
|
||||||
|
resize(c, mx, my, (mw / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), mh - (2*c->bw), 0);
|
||||||
|
mx += WIDTH(c) + iv;
|
||||||
|
} else {
|
||||||
|
resize(c, sx, sy, (sw / sfacts) + ((i - ntop) < srest ? 1 : 0) - (2*c->bw), sh - (2*c->bw), 0);
|
||||||
|
sx += WIDTH(c) + iv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nrowgrid layout + gaps
|
||||||
|
* https://dwm.suckless.org/patches/nrowgrid/
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nrowgrid(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int n;
|
||||||
|
int ri = 0, ci = 0; /* counters */
|
||||||
|
int oh, ov, ih, iv; /* vanitygap settings */
|
||||||
|
unsigned int cx, cy, cw, ch; /* client geometry */
|
||||||
|
unsigned int uw = 0, uh = 0, uc = 0; /* utilization trackers */
|
||||||
|
unsigned int cols, rows = m->nmaster + 1;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
/* count clients */
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
|
||||||
|
/* nothing to do here */
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* force 2 clients to always split vertically */
|
||||||
|
if (FORCE_VSPLIT && n == 2)
|
||||||
|
rows = 1;
|
||||||
|
|
||||||
|
/* never allow empty rows */
|
||||||
|
if (n < rows)
|
||||||
|
rows = n;
|
||||||
|
|
||||||
|
/* define first row */
|
||||||
|
cols = n / rows;
|
||||||
|
uc = cols;
|
||||||
|
cy = m->wy + oh;
|
||||||
|
ch = (m->wh - 2*oh - ih*(rows - 1)) / rows;
|
||||||
|
uh = ch;
|
||||||
|
|
||||||
|
for (c = nexttiled(m->clients); c; c = nexttiled(c->next), ci++) {
|
||||||
|
if (ci == cols) {
|
||||||
|
uw = 0;
|
||||||
|
ci = 0;
|
||||||
|
ri++;
|
||||||
|
|
||||||
|
/* next row */
|
||||||
|
cols = (n - uc) / (rows - ri);
|
||||||
|
uc += cols;
|
||||||
|
cy = m->wy + oh + uh + ih;
|
||||||
|
uh += ch + ih;
|
||||||
|
}
|
||||||
|
|
||||||
|
cx = m->wx + ov + uw;
|
||||||
|
cw = (m->ww - 2*ov - uw) / (cols - ci);
|
||||||
|
uw += cw + iv;
|
||||||
|
|
||||||
|
resize(c, cx, cy, cw - (2*c->bw), ch - (2*c->bw), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Default tile layout + gaps
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
tile(Monitor *m)
|
||||||
|
{
|
||||||
|
unsigned int i, n;
|
||||||
|
int oh, ov, ih, iv;
|
||||||
|
int mx = 0, my = 0, mh = 0, mw = 0;
|
||||||
|
int sx = 0, sy = 0, sh = 0, sw = 0;
|
||||||
|
float mfacts, sfacts;
|
||||||
|
int mrest, srest;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
getgaps(m, &oh, &ov, &ih, &iv, &n);
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sx = mx = m->wx + ov;
|
||||||
|
sy = my = m->wy + oh;
|
||||||
|
mh = m->wh - 2*oh - ih * (MIN(n, m->nmaster) - 1);
|
||||||
|
sh = m->wh - 2*oh - ih * (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 - sw;
|
||||||
|
sx = mx + mw + iv;
|
||||||
|
}
|
||||||
|
|
||||||
|
getfacts(m, mh, sh, &mfacts, &sfacts, &mrest, &srest);
|
||||||
|
|
||||||
|
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 / mfacts) + (i < mrest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
my += HEIGHT(c) + ih;
|
||||||
|
} else {
|
||||||
|
resize(c, sx, sy, sw - (2*c->bw), (sh / sfacts) + ((i - m->nmaster) < srest ? 1 : 0) - (2*c->bw), 0);
|
||||||
|
sy += HEIGHT(c) + ih;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue