Compare commits

...

33 Commits

Author SHA1 Message Date
910f00bd5a I finally updated WM after years 2024-05-29 22:32:14 -06:00
Hiltjo Posthuma
061e9fe9a7 bump version to 6.5 2024-03-19 12:13:16 +01:00
68fdd7e546 back to default color 2024-01-31 23:31:16 -06:00
Hiltjo Posthuma
9f8855343c Makefile: remove the options target
The Makefile used to suppress output (by using @), so this target made sense at
the time.

But the Makefile should be simple and make debugging with less abstractions or
fancy printing.  The Makefile was made verbose and doesn't hide the build
output, so remove this target.

Prompted by a question on the mailing list about the options target.
2023-09-22 15:13:29 +02:00
e4752b14fe fixed merge 2023-08-16 11:07:48 -06:00
7234bf839d Removed open browser keybind 2023-08-16 11:00:34 -06:00
Hiltjo Posthuma
e81f17d4c1 restore SIGCHLD sighandler to default before spawning a program
From sigaction(2):
A child created via fork(2) inherits a copy of its parent's signal dispositions.
During an execve(2), the dispositions of handled signals are reset to the default;
the dispositions of ignored signals are left unchanged.

This refused to start directly some programs from configuring in config.h:

static Key keys[] = {
	MODKEY,                       XK_o,      spawn,          {.v = cmd } },
};

Some reported programs that didn't start were: mpv, anki, dmenu_extended.

Reported by pfx.
Initial patch suggestion by Storkman.
2023-04-09 12:37:14 +02:00
6e1be6552f Better indentation 2023-04-05 14:58:39 -06:00
fe8d0710c3 Fixed no border rendering 2023-03-25 11:20:27 -06:00
NRK
348f6559ab config.mk: update to _XOPEN_SOURCE=700L
SA_NOCLDWAIT is marked as XSI in the posix spec [0] and FreeBSD and NetBSD
seems to more be strict about the feature test macro [1].

so update the macro to use _XOPEN_SOURCE=700L instead, which is equivalent to
_POSIX_C_SOURCE=200809L except that it also unlocks the X/Open System
Interfaces.

[0]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html#tag_13_42
[1]: https://lists.suckless.org/dev/2302/35111.html

Tested on:
* NetBSD 9.3 (fixed).
* FreeBSD 13 (fixed).
* Void Linux musl.
* Void Linux glibc.
* OpenBSD 7.2 (stable).
* Slackware 11.

Reported-by: beastie <pufferfish@riseup.net>
2023-02-17 15:27:34 +01:00
61baa7fa83 Added layout references in config.h 2023-02-05 12:43:15 -06:00
5ed597a0ba Borders stop rendering in monecle layout & gaps disabled 2023-02-05 12:38:17 -06:00
5e39a05bdf added fullscreen patch and status bar renders in all monitors 2022-10-24 23:08:05 -06:00
3ead516da8 Added hide vacant tags patch 2022-10-03 23:12:15 -06:00
b1270a7208 I figured out how to make dragon present in all tags 2021-11-08 15:55:58 -07:00
eaaa2830cb Changed audio intervals 2021-11-02 09:57:29 -07:00
7fc4833e9b added centered master layout 2021-11-01 17:23:54 -07:00
3b5454254c Added gaps in monocle mode 2021-11-01 13:28:30 -07:00
78f68cecc3 changed dwm shortcuts 2021-10-31 14:16:30 -07:00
22d162eb84 Added more modes 2021-10-30 16:35:51 -06:00
fd899805c3 changed main color to blue 2021-10-19 16:39:19 -06:00
c1911b0844 Merge branch 'main' of https://github.com/FisionX/dwm 2021-10-03 12:27:14 -06:00
407d447841 Changed comments 2021-10-03 12:27:05 -06:00
3d00370ba6 changed font 2021-09-30 16:27:28 -06:00
63fd54afca Added old terminal command 2021-09-08 18:11:08 -06:00
44429292f6 Changed terminal shortcut 2021-09-02 11:41:58 -06:00
FisionX
fe9e97930c
Merge pull request #2 from FisionX/my_dwm
Added command for screenshot tool
2021-09-01 22:05:59 -06:00
3c7a3943fa Added command for screenshot tool 2021-09-01 22:03:16 -06:00
FisionX
cbbeea6457
Merge pull request #1 from FisionX/my_dwm
Aded vanitygapc file
2021-08-31 11:52:44 -06:00
bdde719c63 Aded vanitygapc file 2021-08-31 11:50:55 -06:00
db62d25702 Aded singnal updates every time I change kbrlayouts 2021-08-31 10:49:07 -06:00
2707606100 I added keyboard layout shortcuts 2021-08-31 10:11:20 -06:00
3b9011ea97 I added comments for gaps 2021-08-30 21:52:07 -06:00
7 changed files with 1116 additions and 51 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
config.def.h.orig
drw.o
dwm
dwm.c.orig
dwm.c.rej
dwm.o
util.o

View File

@ -6,13 +6,7 @@ include config.mk
SRC = drw.c dwm.c util.c
OBJ = ${SRC:.c=.o}
all: options dwm
options:
@echo dwm build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
all: dwm
.c.o:
${CC} -c ${CFLAGS} $<
@ -48,4 +42,4 @@ uninstall:
rm -f ${DESTDIR}${PREFIX}/bin/dwm\
${DESTDIR}${MANPREFIX}/man1/dwm.1
.PHONY: all options clean dist install uninstall
.PHONY: all clean dist install uninstall

View File

@ -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" };
@ -37,11 +42,26 @@ 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 lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
#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 */
@ -72,6 +92,22 @@ static const 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]} },

172
config.h Normal file
View File

@ -0,0 +1,172 @@
/* See LICENSE file for copyright and license details. */
/* appearance */
static const unsigned int borderpx = 3; /* border pixel of windows */
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 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[] = { "Liberation Mono:size=10" };
static const char dmenufont[] = "Liberation Mono:size=10";
static const char col_gray1[] = "#222222";
static const char col_gray2[] = "#444444";
static const char col_gray3[] = "#bbbbbb";
static const char col_gray4[] = "#eeeeee";
static const char col_cyan[] = "#5C7AEA"; /* Default color */
/*static const char col_cyan[] = "#ff0000"; */
static const char *colors[][3] = {
/* fg bg border */
[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
[SchemeSel] = { col_gray4, col_cyan, col_cyan },
};
/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
static const Rule rules[] = {
/* xprop(1):
* WM_CLASS(STRING) = instance, class
* WM_NAME(STRING) = title
*/
/* class instance title tags mask isfloating monitor */
{ "Firefox", NULL, NULL, 1 << 8, 0, -1 },
{ "Pulseeffects", NULL, NULL, 1 << 2, 0, +1 },
{ NULL, NULL, "dragon", (1 << 9)-1, 1, -1 },
};
/* layout(s) */
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 */
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
#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 */
{ "[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 */
#define MODKEY Mod1Mask
#define TAGKEYS(KEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
/* commands */
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 *termcmd[] = { "st", NULL };
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
static Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
{ MODKEY, XK_e, spawn, SHCMD("setxkbmap us; kill -45 $(pidof dwmblocks)") },
{ MODKEY, XK_s, spawn, SHCMD("setxkbmap es; kill -45 $(pidof dwmblocks)") },
{ MODKEY|ShiftMask, XK_d, spawn, SHCMD("setxkbmap dvorak; kill -45 $(pidof dwmblocks)") },
/* { MODKEY, XK_w, spawn, SHCMD("$BROWSER") },*/
{ MODKEY, XK_a, spawn, SHCMD("$flameshot gui") },
{ MODKEY, XK_b, togglebar, {0} },
{ MODKEY, XK_j, focusstack, {.i = +1 } },
{ MODKEY, XK_k, focusstack, {.i = -1 } },
{ MODKEY, XK_a, incnmaster, {.i = +1 } },
{ MODKEY, XK_d, incnmaster, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
{ MODKEY, XK_Return, zoom, {0} },
{ MODKEY, XK_minus, spawn, SHCMD("pamixer --allow-boost -d 5; kill -44 $(pidof dwmblocks)") },
{ MODKEY|ShiftMask, XK_minus, spawn, SHCMD("pamixer --allow-boost -d 15; kill -44 $(pidof dwmblocks)") },
{ MODKEY, XK_equal, spawn, SHCMD("pamixer --allow-boost -i 5; kill -44 $(pidof dwmblocks)") },
{ MODKEY|ShiftMask, XK_equal, spawn, SHCMD("pamixer --allow-boost -i 15; kill -44 $(pidof dwmblocks)") },
{ MODKEY|Mod4Mask, XK_u, incrgaps, {.i = +3 } }, /* Increase gaps */
{ MODKEY|Mod4Mask|ShiftMask, XK_u, incrgaps, {.i = -3 } }, /* Decrease gaps */
{ MODKEY|Mod4Mask, XK_i, incrigaps, {.i = +3 } }, /* Increase inner gaps */
{ MODKEY|Mod4Mask|ShiftMask, XK_i, incrigaps, {.i = -3 } }, /* Decrease inner gaps */
{ MODKEY|Mod4Mask, XK_o, incrogaps, {.i = +3 } }, /* Increase outer gaps */
{ MODKEY|Mod4Mask|ShiftMask, XK_o, incrogaps, {.i = -3 } }, /* Decrease outer gaps */
/*{ MODKEY|Mod4Mask, XK_6, incrihgaps, {.i = +3 } },*/
/*{ MODKEY|Mod4Mask|ShiftMask, XK_6, incrihgaps, {.i = -3 } },*/
/*{ MODKEY|Mod4Mask, XK_7, incrivgaps, {.i = +3 } },*/
/*{ MODKEY|Mod4Mask|ShiftMask, XK_7, incrivgaps, {.i = -3 } },*/
/*{ MODKEY|Mod4Mask, XK_8, incrohgaps, {.i = +3 } },*/
/*{ MODKEY|Mod4Mask|ShiftMask, XK_8, incrohgaps, {.i = -3 } },*/
/*{ MODKEY|Mod4Mask, XK_9, incrovgaps, {.i = +3 } },*/
/*{ MODKEY|Mod4Mask|ShiftMask, XK_9, incrovgaps, {.i = -3 } },*/
{ MODKEY|Mod4Mask, XK_0, togglegaps, {0} },
{ MODKEY|Mod4Mask|ShiftMask, XK_0, defaultgaps, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY, XK_q, killclient, {0} },
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, /* tile */
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, /* monocle */
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, /* spiral */
{ MODKEY, XK_n, setlayout, {.v = &layouts[3]} }, /* dwindle */
{ MODKEY, XK_i, setlayout, {.v = &layouts[4]} }, /* deck */
{ MODKEY, XK_u, setlayout, {.v = &layouts[5]} }, /* bstack */
{ MODKEY, XK_g, setlayout, {.v = &layouts[7]} }, /* grid */
{ MODKEY|ShiftMask, XK_m, setlayout, {.v = &layouts[11]} },/* centeredmaster */
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY|ShiftMask, XK_f, togglefullscr, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
{ MODKEY, XK_period, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
TAGKEYS( XK_4, 3)
TAGKEYS( XK_5, 4)
TAGKEYS( XK_6, 5)
TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
{ MODKEY|ShiftMask, XK_q, quit, {0} },
};
/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};

View File

@ -1,5 +1,5 @@
# dwm version
VERSION = 6.4
VERSION = 6.5
# Customize below to fit your system
@ -26,7 +26,7 @@ INCS = -I${X11INC} -I${FREETYPEINC}
LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
# flags
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=200809L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
#CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${INCS} ${CPPFLAGS}
LDFLAGS = ${LIBS}

127
dwm.c
View File

@ -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];
@ -199,6 +203,7 @@ static int sendevent(Client *c, Atom proto);
static void sendmon(Client *c, Monitor *m);
static void setclientstate(Client *c, long state);
static void setfocus(Client *c);
static void togglefullscr(const Arg *arg);
static void setfullscreen(Client *c, int fullscreen);
static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg);
@ -433,9 +438,15 @@ buttonpress(XEvent *e)
}
if (ev->window == selmon->barwin) {
i = x = 0;
do
unsigned int occ = 0;
for(c = m->clients; c; c=c->next)
occ |= 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;
@ -641,6 +652,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);
@ -708,7 +723,7 @@ drawbar(Monitor *m)
return;
/* draw status first so it can be overdrawn by tags later */
if (m == selmon) { /* status is only drawn on selected monitor */
if (m == selmon || 1) { /* status is only drawn on selected monitor */
drw_setscheme(drw, scheme[SchemeNorm]);
tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
@ -721,13 +736,12 @@ drawbar(Monitor *m)
}
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 = TEXTW(m->ltsymbol);
@ -1113,18 +1127,47 @@ maprequest(XEvent *e)
void
monocle(Monitor *m)
{
unsigned int n = 0;
unsigned int n = 0, oe = enablegaps;
Client *c;
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
if (n == 0)
return;
if (smartgaps == n) {
oe = 0; // outer gaps disabled
}
n = 0;
for (c = m->clients; c; c = c->next)
if (ISVISIBLE(c))
n++;
if (n > 0) /* override layout symbol */
snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
}
int newx, newy, neww, newh;
for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) {
if (m->gappoh == 0) {
newx = m->wx - c->bw;
newy = m->wy - c->bw;
neww = m->ww;
newh = m->wh;
} else {
newx = m->wx + m->gappoh*oe - c->bw;
newy = m->wy + m->gappoh*oe - c->bw;
neww = m->ww - 2 * (m->gappoh*oe + c->bw);
newh = m->wh - 2 * (m->gappoh*oe + c->bw);
}
applysizehints(c, &newx, &newy, &neww, &newh, 0);
if (neww < m->ww)
newx = m->wx + (m->ww - (neww + 2 * c->bw)) / 2;
if (newh < m->wh)
newy = m->wy + (m->wh - (newh + 2 * c->bw)) / 2;
resize(c, newx, newy, neww, newh, 0);
}
}
void
motionnotify(XEvent *e)
{
@ -1286,12 +1329,26 @@ void
resizeclient(Client *c, int x, int y, int w, int h)
{
XWindowChanges wc;
unsigned int n;
Client *nbc;
c->oldx = c->x; c->x = wc.x = x;
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;
for (n = 0, nbc = nexttiled(c->mon->clients); nbc; nbc = nexttiled(nbc->next), n++);
if (c->isfloating || c->mon->lt[c->mon->sellt]->arrange == NULL) {
} else {
if (c->mon->lt[c->mon->sellt]->arrange == monocle && !enablegaps || n == 1 && !enablegaps) {
wc.border_width = 0;
c->w = wc.width += c->bw * 2;
c->h = wc.height += c->bw * 2;
}
}
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
configure(c);
XSync(dpy, False);
@ -1647,12 +1704,20 @@ showhide(Client *c)
void
spawn(const Arg *arg)
{
struct sigaction sa;
if (arg->v == dmenucmd)
dmenumon[0] = '0' + selmon->num;
if (fork() == 0) {
if (dpy)
close(ConnectionNumber(dpy));
setsid();
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &sa, NULL);
execvp(((char **)arg->v)[0], (char **)arg->v);
die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]);
}
@ -1676,34 +1741,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);
if (my + HEIGHT(c) < m->wh)
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);
if (ty + HEIGHT(c) < m->wh)
ty += HEIGHT(c);
}
}
void
togglebar(const Arg *arg)
{
@ -1713,6 +1750,13 @@ togglebar(const Arg *arg)
arrange(selmon);
}
void
togglefullscr(const Arg *arg)
{
if (selmon->sel)
setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
}
void
togglefloating(const Arg *arg)
{
@ -1997,9 +2041,11 @@ updatesizehints(Client *c)
void
updatestatus(void)
{
Monitor *m;
if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
strcpy(stext, "dwm-"VERSION);
drawbar(selmon);
for(m = mons; m; m = m->next)
drawbar(m);
}
void
@ -2155,3 +2201,4 @@ main(int argc, char *argv[])
XCloseDisplay(dpy);
return EXIT_SUCCESS;
}

809
vanitygaps.c Normal file
View File

@ -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;
}
}