1 Commits

Author SHA1 Message Date
Fabian Schmidt
182988bfc7 Add gaps 2020-06-01 20:50:56 +02:00
2 changed files with 165 additions and 84 deletions

View File

@@ -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 = 10; /* 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 = 10; /* vert outer gap between windows and screen edge */
static const 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" };
@@ -70,6 +75,22 @@ static Key keys[] = {
{ MODKEY, XK_d, incnmaster, {.i = -1 } }, { MODKEY, XK_d, incnmaster, {.i = -1 } },
{ 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|Mod4Mask, XK_h, incrgaps, {.i = +1 } },
{ MODKEY|Mod4Mask, XK_l, incrgaps, {.i = -1 } },
{ MODKEY|Mod4Mask|ShiftMask, XK_h, incrogaps, {.i = +1 } },
{ MODKEY|Mod4Mask|ShiftMask, XK_l, incrogaps, {.i = -1 } },
{ MODKEY|Mod4Mask|ControlMask, XK_h, incrigaps, {.i = +1 } },
{ MODKEY|Mod4Mask|ControlMask, XK_l, incrigaps, {.i = -1 } },
{ MODKEY|Mod4Mask, XK_0, togglegaps, {0} },
{ MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} },
{ MODKEY, XK_y, incrihgaps, {.i = +1 } },
{ MODKEY, XK_o, incrihgaps, {.i = -1 } },
{ MODKEY|ControlMask, XK_y, incrivgaps, {.i = +1 } },
{ MODKEY|ControlMask, XK_o, incrivgaps, {.i = -1 } },
{ MODKEY|Mod4Mask, XK_y, incrohgaps, {.i = +1 } },
{ MODKEY|Mod4Mask, XK_o, incrohgaps, {.i = -1 } },
{ MODKEY|ShiftMask, XK_y, incrovgaps, {.i = +1 } },
{ MODKEY|ShiftMask, XK_o, incrovgaps, {.i = -1 } },
{ MODKEY, XK_Return, zoom, {0} }, { MODKEY, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} }, { MODKEY, XK_Tab, view, {0} },
{ MODKEY|ShiftMask, XK_c, killclient, {0} }, { MODKEY|ShiftMask, XK_c, killclient, {0} },
@@ -103,9 +124,7 @@ static Button buttons[] = {
{ ClkLtSymbol, 0, Button1, setlayout, {0} }, { ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} }, { ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button1, sigdwmblocks, {.i = 1} }, { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkStatusText, 0, Button2, sigdwmblocks, {.i = 2} },
{ ClkStatusText, 0, Button3, sigdwmblocks, {.i = 3} },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} }, { ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} }, { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} }, { ClkClientWin, MODKEY, Button3, resizemouse, {0} },

224
dwm.c
View File

@@ -119,6 +119,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];
@@ -156,7 +160,6 @@ static void clientmessage(XEvent *e);
static void configure(Client *c); static void configure(Client *c);
static void configurenotify(XEvent *e); static void configurenotify(XEvent *e);
static void configurerequest(XEvent *e); static void configurerequest(XEvent *e);
static void copyvalidchars(char *text, char *rawtext);
static Monitor *createmon(void); static Monitor *createmon(void);
static void destroynotify(XEvent *e); static void destroynotify(XEvent *e);
static void detach(Client *c); static void detach(Client *c);
@@ -170,7 +173,6 @@ static void focus(Client *c);
static void focusin(XEvent *e); static void focusin(XEvent *e);
static void focusmon(const Arg *arg); static void focusmon(const Arg *arg);
static void focusstack(const Arg *arg); static void focusstack(const Arg *arg);
static int getdwmblockspid();
static Atom getatomprop(Client *c, Atom prop); static Atom getatomprop(Client *c, Atom prop);
static int getrootptr(int *x, int *y); static int getrootptr(int *x, int *y);
static long getstate(Window w); static long getstate(Window w);
@@ -202,13 +204,22 @@ static void sendmon(Client *c, Monitor *m);
static void setclientstate(Client *c, long state); static void setclientstate(Client *c, long state);
static void setfocus(Client *c); static void setfocus(Client *c);
static void setfullscreen(Client *c, int fullscreen); static void setfullscreen(Client *c, int fullscreen);
static void setgaps(int oh, int ov, int ih, int iv);
static void incrgaps(const Arg *arg);
static void incrigaps(const Arg *arg);
static void incrogaps(const Arg *arg);
static void incrohgaps(const Arg *arg);
static void incrovgaps(const Arg *arg);
static void incrihgaps(const Arg *arg);
static void incrivgaps(const Arg *arg);
static void togglegaps(const Arg *arg);
static void defaultgaps(const Arg *arg);
static void setlayout(const Arg *arg); static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg); static void setmfact(const Arg *arg);
static void setup(void); static void setup(void);
static void seturgent(Client *c, int urg); 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 sigdwmblocks(const Arg *arg);
static void spawn(const Arg *arg); static void spawn(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);
@@ -241,12 +252,10 @@ static void zoom(const Arg *arg);
/* variables */ /* variables */
static const char broken[] = "broken"; static const char broken[] = "broken";
static char stext[256]; static char stext[256];
static char rawstext[256];
static int dwmblockssig;
pid_t dwmblockspid = 0;
static int screen; static int screen;
static int sw, sh; /* X display screen geometry width, height */ static int sw, sh; /* X display screen geometry width, height */
static int bh, blw = 0; /* bar geometry */ static int bh, blw = 0; /* bar geometry */
static int enablegaps = 1; /* enables gaps, used by togglegaps */
static int lrpad; /* sum of left and right padding for text */ static int lrpad; /* sum of left and right padding for text */
static int (*xerrorxlib)(Display *, XErrorEvent *); static int (*xerrorxlib)(Display *, XErrorEvent *);
static unsigned int numlockmask = 0; static unsigned int numlockmask = 0;
@@ -446,25 +455,9 @@ buttonpress(XEvent *e)
arg.ui = 1 << i; arg.ui = 1 << i;
} else if (ev->x < x + blw) } else if (ev->x < x + blw)
click = ClkLtSymbol; click = ClkLtSymbol;
else if (ev->x > (x = selmon->ww - TEXTW(stext) + lrpad)) { else if (ev->x > selmon->ww - TEXTW(stext))
click = ClkStatusText; click = ClkStatusText;
char *text = rawstext; else
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; click = ClkWinTitle;
} else if ((c = wintoclient(ev->window))) { } else if ((c = wintoclient(ev->window))) {
focus(c); focus(c);
@@ -650,19 +643,6 @@ configurerequest(XEvent *e)
XSync(dpy, False); 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 * Monitor *
createmon(void) createmon(void)
{ {
@@ -674,6 +654,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);
@@ -907,18 +891,6 @@ getatomprop(Client *c, Atom prop)
return atom; 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 int
getrootptr(int *x, int *y) getrootptr(int *x, int *y)
{ {
@@ -1545,6 +1517,111 @@ setfullscreen(Client *c, int fullscreen)
} }
} }
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)
{
enablegaps = !enablegaps;
arrange(selmon);
}
void
defaultgaps(const Arg *arg)
{
setgaps(gappoh, gappov, gappih, gappiv);
}
void
incrgaps(const Arg *arg)
{
setgaps(
selmon->gappoh + arg->i,
selmon->gappov + arg->i,
selmon->gappih + arg->i,
selmon->gappiv + arg->i
);
}
void
incrigaps(const Arg *arg)
{
setgaps(
selmon->gappoh,
selmon->gappov,
selmon->gappih + arg->i,
selmon->gappiv + arg->i
);
}
void
incrogaps(const Arg *arg)
{
setgaps(
selmon->gappoh + arg->i,
selmon->gappov + arg->i,
selmon->gappih,
selmon->gappiv
);
}
void
incrohgaps(const Arg *arg)
{
setgaps(
selmon->gappoh + arg->i,
selmon->gappov,
selmon->gappih,
selmon->gappiv
);
}
void
incrovgaps(const Arg *arg)
{
setgaps(
selmon->gappoh,
selmon->gappov + arg->i,
selmon->gappih,
selmon->gappiv
);
}
void
incrihgaps(const Arg *arg)
{
setgaps(
selmon->gappoh,
selmon->gappov,
selmon->gappih + arg->i,
selmon->gappiv
);
}
void
incrivgaps(const Arg *arg)
{
setgaps(
selmon->gappoh,
selmon->gappov,
selmon->gappih,
selmon->gappiv + arg->i
);
}
void void
setlayout(const Arg *arg) setlayout(const Arg *arg)
{ {
@@ -1684,23 +1761,6 @@ sigchld(int unused)
while (0 < waitpid(-1, NULL, WNOHANG)); 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 void
spawn(const Arg *arg) spawn(const Arg *arg)
{ {
@@ -1738,28 +1798,32 @@ tagmon(const Arg *arg)
void void
tile(Monitor *m) tile(Monitor *m)
{ {
unsigned int i, n, h, mw, my, ty; unsigned int i, n, h, r, oe = enablegaps, ie = enablegaps, mw, my, ty;
Client *c; Client *c;
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
if (n == 0) if (n == 0)
return; return;
if (smartgaps == n) {
oe = 0; // outer gaps disabled
}
if (n > m->nmaster) if (n > m->nmaster)
mw = m->nmaster ? m->ww * m->mfact : 0; mw = m->nmaster ? (m->ww + m->gappiv*ie) * m->mfact : 0;
else else
mw = m->ww; mw = m->ww - 2*m->gappov*oe + m->gappiv*ie;
for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) for (i = 0, my = ty = m->gappoh*oe, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
if (i < m->nmaster) { if (i < m->nmaster) {
h = (m->wh - my) / (MIN(n, m->nmaster) - i); r = MIN(n, m->nmaster) - i;
resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); h = (m->wh - my - m->gappoh*oe - m->gappih*ie * (r - 1)) / r;
if (my + HEIGHT(c) < m->wh) resize(c, m->wx + m->gappov*oe, m->wy + my, mw - (2*c->bw) - m->gappiv*ie, h - (2*c->bw), 0);
my += HEIGHT(c); my += HEIGHT(c) + m->gappih*ie;
} else { } else {
h = (m->wh - ty) / (n - i); r = n - i;
resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); h = (m->wh - ty - m->gappoh*oe - m->gappih*ie * (r - 1)) / r;
if (ty + HEIGHT(c) < m->wh) resize(c, m->wx + mw + m->gappov*oe, m->wy + ty, m->ww - mw - (2*c->bw) - 2*m->gappov*oe, h - (2*c->bw), 0);
ty += HEIGHT(c); ty += HEIGHT(c) + m->gappih*ie;
} }
} }
@@ -2054,10 +2118,8 @@ updatesizehints(Client *c)
void void
updatestatus(void) updatestatus(void)
{ {
if (!gettextprop(root, XA_WM_NAME, rawstext, sizeof(rawstext))) if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
strcpy(stext, "dwm-"VERSION); strcpy(stext, "dwm-"VERSION);
else
copyvalidchars(stext, rawstext);
drawbar(selmon); drawbar(selmon);
} }