The Great dwm & Suckless Hacking Thread

Share your hacks, custom config.h’s, whatever you have Suckless you have.

These are the patches I apply to the custom dwm port I use in OpenBSD:

config.mk

--- config.mk.orig
+++ config.mk
@@ -11,14 +11,14 @@ X11INC = /usr/X11R6/include
 X11LIB = /usr/X11R6/lib
 
 # Xinerama, comment if you don't want it
-XINERAMALIBS  = -lXinerama
-XINERAMAFLAGS = -DXINERAMA
+#XINERAMALIBS  = -lXinerama
+#XINERAMAFLAGS = -DXINERAMA
 
 # freetype
 FREETYPELIBS = -lfontconfig -lXft
 FREETYPEINC = /usr/include/freetype2
 # OpenBSD (uncomment)
-#FREETYPEINC = ${X11INC}/freetype2
+FREETYPEINC = ${X11INC}/freetype2
 
 # includes and libs
 INCS = -I${X11INC} -I${FREETYPEINC}
@@ -27,8 +27,8 @@ LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIB
 # flags
 CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_C_SOURCE=2 -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}
+CFLAGS   += -std=c99 -pedantic -Wall -Wno-deprecated-declarations ${INCS} ${CPPFLAGS}
+LDFLAGS  += ${LIBS}
 
 # Solaris
 #CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"

config.def.h

--- config.def.h.orig
+++ config.def.h
@@ -2,16 +2,16 @@
 
 /* appearance */
 static const unsigned int borderpx  = 1;        /* border pixel of windows */
-static const unsigned int snap      = 32;       /* snap pixel */
+static const unsigned int snap      = 10;       /* snap pixel */
 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" };
-static const char dmenufont[]       = "monospace: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[]        = "#005577";
+static const char *fonts[]          = { "sans:size=12" };
+static const char dmenufont[]       = "sans:size=12";
+static const char col_gray1[]       = "#313233";
+static const char col_gray2[]       = "#000000";
+static const char col_gray3[]       = "#bfbfbf";
+static const char col_gray4[]       = "#313233";
+static const char col_cyan[]        = "#cecece";
 static const char *colors[][3]      = {
 	/*               fg         bg         border   */
 	[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
@@ -19,7 +19,7 @@ static const char *colors[][3]      = {
 };
 
 /* tagging */
-static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+static const char *tags[] = { "00", "01", "10", "11", "web" };
 
 static const Rule rules[] = {
 	/* xprop(1):
@@ -28,23 +28,23 @@ static const Rule rules[] = {
 	 */
 	/* class      instance    title       tags mask     isfloating   monitor */
 	{ "Gimp",     NULL,       NULL,       0,            1,           -1 },
-	{ "Firefox",  NULL,       NULL,       1 << 8,       0,           -1 },
+	{ "Chromium",  NULL,       NULL,       1 << 4,       0,           -1 },
 };
 
 /* layout(s) */
-static const float mfact     = 0.55; /* factor of master area size [0.05..0.95] */
+static const float mfact     = 0.65; /* 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 resizehints = 0;    /* 1 means respect size hints in tiled resizals */
 
 static const Layout layouts[] = {
 	/* symbol     arrange function */
-	{ "[]=",      tile },    /* first entry is default */
-	{ "><>",      NULL },    /* no layout function means floating behavior */
+	{ "[T]",      tile },    /* first entry is default */
+	{ "[F]",      NULL },    /* no layout function means floating behavior */
 	{ "[M]",      monocle },
 };
 
 /* key definitions */
-#define MODKEY Mod1Mask
+#define MODKEY Mod4Mask
 #define TAGKEYS(KEY,TAG) \
 	{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
 	{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
@@ -56,8 +56,8 @@ static const Layout layouts[] = {
 
 /* 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 };
+static const char *dmenucmd[] = { "dmenu_run", "-b", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
+static const char *termcmd[]  = { "xterm", NULL };
 
 static Key keys[] = {
 	/* modifier                     key        function        argument */
@@ -68,8 +68,8 @@ static Key keys[] = {
 	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
 	{ MODKEY,                       XK_i,      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_h,      setmfact,       {.f = -0.01} },
+	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.01} },
 	{ MODKEY,                       XK_Return, zoom,           {0} },
 	{ MODKEY,                       XK_Tab,    view,           {0} },
 	{ MODKEY|ShiftMask,             XK_c,      killclient,     {0} },

dwm.c

$OpenBSD$

Index: dwm.c
--- dwm.c.orig
+++ dwm.c
@@ -49,7 +49,8 @@
 #define CLEANMASK(mask)         (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
 #define INTERSECT(x,y,w,h,m)    (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
                                * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
-#define ISVISIBLE(C)            ((C->tags & C->mon->tagset[C->mon->seltags]))
+#define ISVISIBLEONTAG(C, T)    ((C->tags & T))
+#define ISVISIBLE(C)            ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags])
 #define LENGTH(X)               (sizeof X / sizeof X[0])
 #define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
 #define WIDTH(X)                ((X)->w + 2 * (X)->bw)
@@ -147,6 +148,7 @@ static int applysizehints(Client *c, int *x, int *y, i
 static void arrange(Monitor *m);
 static void arrangemon(Monitor *m);
 static void attach(Client *c);
+static void attachaside(Client *c);
 static void attachstack(Client *c);
 static void buttonpress(XEvent *e);
 static void checkotherwm(void);
@@ -169,6 +171,7 @@ static void focus(Client *c);
 static void focusin(XEvent *e);
 static void focusmon(const Arg *arg);
 static void focusstack(const Arg *arg);
+static Atom getatomprop(Client *c, Atom prop);
 static int getrootptr(int *x, int *y);
 static long getstate(Window w);
 static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
@@ -183,6 +186,7 @@ static void maprequest(XEvent *e);
 static void monocle(Monitor *m);
 static void motionnotify(XEvent *e);
 static void movemouse(const Arg *arg);
+static Client *nexttagged(Client *c);
 static Client *nexttiled(Client *c);
 static void pop(Client *);
 static void propertynotify(XEvent *e);
@@ -407,6 +411,18 @@ attach(Client *c)
 }
 
 void
+attachaside(Client *c) {
+	Client *at = nexttagged(c);
+	if(!at) {
+		attach(c);
+		return;
+		}
+	c->next = at->next;
+	at->next = c;
+}
+
+
+void
 attachstack(Client *c)
 {
 	c->snext = c->mon->stack;
@@ -695,7 +711,7 @@ dirtomon(int dir)
 void
 drawbar(Monitor *m)
 {
-	int x, w, sw = 0;
+	int x, w, tw = 0;
 	int boxs = drw->fonts->h / 9;
 	int boxw = drw->fonts->h / 6 + 2;
 	unsigned int i, occ = 0, urg = 0;
@@ -704,8 +720,8 @@ drawbar(Monitor *m)
 	/* draw status first so it can be overdrawn by tags later */
 	if (m == selmon) { /* status is only drawn on selected monitor */
 		drw_setscheme(drw, scheme[SchemeNorm]);
-		sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
-		drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0);
+		tw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
+		drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0);
 	}
 
 	for (c = m->clients; c; c = c->next) {
@@ -728,7 +744,7 @@ drawbar(Monitor *m)
 	drw_setscheme(drw, scheme[SchemeNorm]);
 	x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
 
-	if ((w = m->ww - sw - x) > bh) {
+	if ((w = m->ww - tw - x) > bh) {
 		if (m->sel) {
 			drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
 			drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
@@ -1062,7 +1078,7 @@ manage(Window w, XWindowAttributes *wa)
 		c->isfloating = c->oldstate = trans != None || c->isfixed;
 	if (c->isfloating)
 		XRaiseWindow(dpy, c->win);
-	attach(c);
+	attachaside(c);
 	attachstack(c);
 	XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
 		(unsigned char *) &(c->win), 1);
@@ -1192,6 +1208,16 @@ movemouse(const Arg *arg)
 	}
 }
 
+ Client *
+nexttagged(Client *c) {
+	Client *walked = c->mon->clients;
+	for(;
+		walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags));
+		walked = walked->next
+	);
+	return walked;
+}
+
 Client *
 nexttiled(Client *c)
 {
@@ -1417,7 +1443,7 @@ sendmon(Client *c, Monitor *m)
 	detachstack(c);
 	c->mon = m;
 	c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
-	attach(c);
+	attachaside(c);
 	attachstack(c);
 	focus(NULL);
 	arrange(NULL);
@@ -1520,7 +1546,7 @@ setmfact(const Arg *arg)
 	if (!arg || !selmon->lt[selmon->sellt]->arrange)
 		return;
 	f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
-	if (f < 0.1 || f > 0.9)
+	if (f < 0.05 || f > 0.95)
 		return;
 	selmon->mfact = f;
 	arrange(selmon);
@@ -1545,7 +1571,7 @@ setup(void)
 	if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
 		die("no fonts could be loaded.");
 	lrpad = drw->fonts->h;
-	bh = drw->fonts->h + 2;
+	bh = drw->fonts->h + 4;
 	updategeom();
 	/* init atoms */
 	utf8string = XInternAtom(dpy, "UTF8_STRING", False);
@@ -1688,11 +1714,13 @@ tile(Monitor *m)
 		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);
+			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);
-			ty += HEIGHT(c);
+			if (ty + HEIGHT(c) < m->wh)
+				ty += HEIGHT(c);
 		}
 }
 
@@ -1898,6 +1926,7 @@ updategeom(void)
 					detachstack(c);
 					c->mon = mons;
 					attach(c);
+					attachaside(c);
 					attachstack(c);
 				}
 				if (m == selmon)

I can’t remember exactly but I think that’s with the attachaside patch, a small increase in the height of the panel and all of the Xinerama ifdefs stripped out because bloat.

2 Likes

Attachaside is a great patch. It was what my previous dwm/polybar build was missing.

2 Likes

Patches i use: taggrid, alwayscenter, colorbar, cool-autostart, restartsig, swallow, switchtotag.

My config.h (nothing special):

static const unsigned int borderpx  = 1;        /* border pixel of windows */
static const unsigned int snap      = 32;       /* snap pixel */
static const int swallowfloating    = 1;        /* 1 means swallow floating windows by default */
static const int showbar            = 1;        /* 0 means no bar */
static const int topbar             = 1;        /* 0 means bottom bar */
static const char *fonts[]          = { "UW Ttyp0:pixelsize=14" };
static const char dmenufont[]       = "UW Ttyp0:pixelsize=15";
static const char col_gray1[]       = "#151515";
static const char col_gray2[]       = "#444444";
static const char col_gray3[]       = "#bbbbbb";
static const char col_gray4[]       = "#eeeeee";
static const char col_cyan[]        = "#242B26";
static const char col_cyan2[]       = "#7B7B79";
static const char *colors[][3]      = {
	/*               fg         bg         border   */
	[SchemeNorm] = { col_gray3, col_gray1, col_gray1 },
	[SchemeSel]  = { col_gray4, col_cyan2,  col_cyan2  },
	[SchemeStatus]  = { col_gray3, col_cyan,  "#000000"  }, // Statusbar right {text,background,not used but cannot be empty}
	[SchemeTagsSel]  = { col_cyan, col_gray1,  "#000000"  }, // Tagbar left selected {text,background,not used but cannot be empty}
    [SchemeTagsNorm]  = { col_gray3, col_gray1,  "#000000"  }, // Tagbar left unselected {text,background,not used but cannot be empty}
    [SchemeInfoSel]  = { col_gray4, col_gray1,  "#000000"  }, // infobar middle  selected {text,background,not used but cannot be empty}
    [SchemeInfoNorm]  = { col_gray3, col_gray1,  "#000000"  }, // infobar middle  unselected {text,background,not used but cannot be empty}
};

#include <X11/XF86keysym.h>

static const char *const autostart[] = {
	"slstatus", NULL,
        "xcompmgr", "-CcfF", "-I-.015", "-O-.03", "-D1", "-t-1", "-l-3", "-r6.2", "-o.5", NULL, 
        "xset", "r", "rate", "250", "60", NULL,        
        "xset", "-dpms", NULL,
        "xset", "s", "noblank", NULL,
        "xset", "s", "off", NULL,  
        "xset", "+fp", "/usr/share/fonts/misc", NULL,         
        "setroot", "-c", "/home/subjunkie/Walls/bpw2.png", NULL,                                     
        NULL /* terminate */
};

/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6" };

/* grid of tags */
#define DRAWCLASSICTAGS             1 << 0
#define DRAWTAGGRID                 1 << 1

#define SWITCHTAG_UP                1 << 0
#define SWITCHTAG_DOWN              1 << 1
#define SWITCHTAG_LEFT              1 << 2
#define SWITCHTAG_RIGHT             1 << 3
#define SWITCHTAG_TOGGLETAG         1 << 4
#define SWITCHTAG_TAG               1 << 5
#define SWITCHTAG_VIEW              1 << 6
#define SWITCHTAG_TOGGLEVIEW        1 << 7

static const unsigned int drawtagmask = DRAWTAGGRID; /* | DRAWCLASSICTAGS to show classic row of tags */
static const int tagrows = 1;

static const Rule rules[] = {
	/* xprop(1):
	 *	WM_CLASS(STRING) = instance, class
	 *	WM_NAME(STRING) = title
	 */
	/* class     instance  title           tags mask  switchtotag  isfloating  isterminal  noswallow  monitor */
	{ "firefox",  NULL,       NULL,        1 << 5,    1,           0,            0,            -1,     -1 },
        {  NULL,      NULL,       "cmus",      1 << 3,    1,           1,            1,            -1,     -1 },
        {  NULL,      NULL,       "noice",     1 << 1,    1,           0,            1,             0,     -1 },
        { "sxiv",     NULL,       NULL,        1 >> 3,    0,           0,            0,            -1,     -1 },  
        { "St",      NULL,     NULL,           0,         0,           0,            1,             0,     -1 }, 
	{ NULL,      NULL,     "Event Tester", 0,         0,           0,            0,            -1,     -1 }, /* xev */
};

/* 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 Layout layouts[] = {
	/* symbol     arrange function */
	{ "[T]=",      tile },    /* first entry is default */
	{ "[F]",      NULL },    /* no layout function means floating behavior */
	{ "[M]",      monocle },
};

/* key definitions */
#define MODKEY Mod4Mask
#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 };
static const char *noicecmd[]  = { "st", "-e", "noice", NULL };
static const char *cmuscmd[] = { "st", "-e", "cmus", NULL };
static const char *mutecmd[] = { "amixer", "-q", "set", "Master", "toggle", NULL };
static const char *volupcmd[] = { "amixer", "-q", "set", "Master", "5%+", "unmute", NULL };
static const char *voldowncmd[] = { "amixer", "-q", "set", "Master", "5%-", "unmute", NULL };

static Key keys[] = {
	/* modifier                     key        function        argument */
	{ 0, XF86XK_AudioMute,          spawn, {.v = mutecmd } },
        { 0, XF86XK_AudioLowerVolume,   spawn, {.v = voldowncmd } },
        { 0, XF86XK_AudioRaiseVolume,   spawn, {.v = volupcmd } },
	{ MODKEY,                       XK_d,      spawn,          {.v = dmenucmd } },
	{ MODKEY,                       XK_Return, spawn,          {.v = termcmd } },
        { MODKEY|ShiftMask,             XK_e,      spawn,          {.v = noicecmd } },
        { MODKEY|ShiftMask,             XK_n,      spawn,          {.v = cmuscmd } },
        { MODKEY,                       XK_Print,  spawn,          {.v = (char *[]){"scrot", NULL}} },
	{ MODKEY|ShiftMask,             XK_Print,  spawn,          {.v = (char *[]){"scrot", "-s", NULL}} },
	{ MODKEY,                       XK_b,      togglebar,      {0} },
	{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
	{ MODKEY,                       XK_i,      incnmaster,     {.i = +1 } },
	{ MODKEY|ShiftMask,             XK_d,      incnmaster,     {.i = -1 } },
	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} },
	{ MODKEY|ShiftMask,             XK_Return, zoom,           {0} },
	{ MODKEY,                       XK_Tab,    view,           {0} },
	{ MODKEY,                       XK_q,      killclient,     {0} },
	{ MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} },
	{ MODKEY,                       XK_f,      setlayout,      {.v = &layouts[1]} },
	{ MODKEY,                       XK_m,      setlayout,      {.v = &layouts[2]} },
	{ MODKEY,                       XK_space,  setlayout,      {0} },
	{ MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
	{ MODKEY,                       XK_0,      view,           {.ui = ~0 } },
	{ MODKEY|ShiftMask,             XK_0,      tag,            {.ui = ~0 } },
	{ MODKEY,                       XK_comma,  focusmon,       {.i = -1 } },
	{ MODKEY,                       XK_period, focusmon,       {.i = +1 } },
	{ MODKEY|ShiftMask,             XK_comma,  tagmon,         {.i = -1 } },
	{ MODKEY|ShiftMask,             XK_period, tagmon,         {.i = +1 } },
	TAGKEYS(                        XK_1,                      0)
	TAGKEYS(                        XK_2,                      1)
	TAGKEYS(                        XK_3,                      2)
	TAGKEYS(                        XK_4,                      3)
	TAGKEYS(                        XK_5,                      4)
	TAGKEYS(                        XK_6,                      5)
	TAGKEYS(                        XK_7,                      6)
	TAGKEYS(                        XK_8,                      7)
	TAGKEYS(                        XK_9,                      8)
	{ MODKEY|ShiftMask,             XK_q,      quit,           {0} },
	{ MODKEY|ControlMask|ShiftMask, XK_q,      quit,           {1} }, 

    { MODKEY|ControlMask,           XK_Up,     switchtag,      { .ui = SWITCHTAG_UP     | SWITCHTAG_VIEW } },
    { MODKEY|ControlMask,           XK_Down,   switchtag,      { .ui = SWITCHTAG_DOWN   | SWITCHTAG_VIEW } },
    { MODKEY|ControlMask,           XK_Right,  switchtag,      { .ui = SWITCHTAG_RIGHT  | SWITCHTAG_VIEW } },
    { MODKEY|ControlMask,           XK_Left,   switchtag,      { .ui = SWITCHTAG_LEFT   | SWITCHTAG_VIEW } },

    { MODKEY|Mod4Mask,              XK_Up,     switchtag,      { .ui = SWITCHTAG_UP     | SWITCHTAG_TAG | SWITCHTAG_VIEW } },
    { MODKEY|Mod4Mask,              XK_Down,   switchtag,      { .ui = SWITCHTAG_DOWN   | SWITCHTAG_TAG | SWITCHTAG_VIEW } },
    { MODKEY|Mod4Mask,              XK_Right,  switchtag,      { .ui = SWITCHTAG_RIGHT  | SWITCHTAG_TAG | SWITCHTAG_VIEW } },
    { MODKEY|Mod4Mask,              XK_Left,   switchtag,      { .ui = SWITCHTAG_LEFT   | SWITCHTAG_TAG | SWITCHTAG_VIEW } },
};

/* 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]} },
	{ 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} },
};
1 Like

patches -

dwm-attachaside-20180126-db22360.diff
dwm-bottomstack-20160719-56a31dc.diff
dwm-cyclelayouts-20180524-6.2.diff
dwm-focusonclick-20171030-6aa8e37.diff
dwm-gaplessgrid-20160731-56a31dc.diff
dwm-moveresize-20200609-46c8838.diff
dwm-notitle-6.2.diff
dwm-pertag-6.2.diff
dwm-statusbutton-20180524-c8e9479.diff
dwm-switchtotag-6.2.diff
dwm-systray-20200610-f09418b.diff
dwm-uselessgap-20200719-bb2e722.diff

I like to remove the statusbar window title, and added the statusbutton for jgmenu. The rest are typical patches. Jgmenu also enabled with Mouse1 click on the root window (I always switch from Mouse3 to Mouse1 for that).

This setup requires some manual patching. The notitle, statusbutton, and systemtray patches have to be done manually otherwise the build fails.

slstatus for system information.

config.h

/* See LICENSE file for copyright and license details. */

/* gappless grid layout */
#include "gaplessgrid.c"

/* multimedia keys */
#include <X11/XF86keysym.h>

/* appearance */
static const unsigned int borderpx  = 1;        /* border pixel of windows */
static const unsigned int gappx     = 0;        /* gaps between windows */
static const unsigned int snap      = 16;       /* snap pixel */
static const unsigned int systraypinning = 0;   /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */
static const unsigned int systrayspacing = 2;   /* systray spacing */
static const int systraypinningfailfirst = 1;   /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/
static const int showsystray        = 1;     /* 0 means no systray */
static const int showbar            = 1;        /* 0 means no bar */
static const int topbar             = 1;        /* 0 means bottom bar */
static const int focusonwheel       = 0;
static const char buttonbar[]       = "[=]";
static const char *fonts[]          = { "Roboto Mono:size=10:antialias=true:autohint=true" };
static const char dmenufont[]       = "Roboto:size=10:antialias=true:autohint=true";
static const char col_gray1[]       = "#18191A";
static const char col_gray2[]       = "#171717";
static const char col_gray3[]       = "#CCCCCC";
static const char col_gray4[]       = "#DFDFDF";
static const char col_gray5[]       = "#333333";
static const char col_blue1[]       = "#3D4780";
static const char col_blue2[]       = "#2E313B";
static const char *colors[][3]      = {
	/*               fg         bg         border   */
	[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
	[SchemeSel]  = { col_gray4, col_blue2, col_blue2  },
};

/* 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     switchtotag    isfloating      monitor */
	{ "Gimp",                NULL,         NULL,                          1 << 3,          1,              0,          -1 },
	{ "Gimp",                NULL,         "Open Image",                  1 << 3,          1,              1,          -1 },
	{ "Gimp",                NULL,         "Scale Image",                 1 << 3,          1,              1,          -1 },
	{ "Gimp",                NULL,         "Export Image",                1 << 3,          1,              1,          -1 },
	{ "Gimp",                NULL,         "Save Image",                  1 << 3,          1,              1,          -1 },
	{ "Gimp",                NULL,         "Change Foreground Color",     1 << 3,          1,              1,          -1 },
	{ "Gimp",                NULL,         "Change Background Color",     1 << 3,          1,              1,          -1 },
	{ "Gimp",                NULL,         "Create New Image",            1 << 3,          1,              1,          -1 },
	{ "Transmission-gtk",    NULL,         NULL,                          1 << 7,          1,              0,          -1 },
	{ "Audacious",           NULL,         NULL,                          1 << 8,          1,              1,          -1 },
	{ "Deadbeef",            NULL,         NULL,                          1 << 8,          1,              1,          -1 },
	{ "Vlc",                 NULL,         NULL,                          1 << 8,          1,              0,          -1 },
	{ "Yad",                 NULL,         NULL,                          0,               0,              1,          -1 },
	{ "Sxiv",                NULL,         NULL,                          0,               0,              1,          -1 },
	{ "Galculator",          NULL,         NULL,                          0,               0,              1,          -1 },
	{ "XCalc",               NULL,         NULL,                          0,               0,              1,          -1 },
	{ "Thunderbird",         NULL,         NULL,                          0,               0,              0,          -1 },
	{ "Thunderbird",         "Dialog",     NULL,                          0,               0,              0,          -1 },	
	{ "Thunderbird",         NULL,         "Write",                       0,               0,              1,          -1 },
	{ "Thunderbird",         NULL,         "Sending Message",             0,               0,              1,          -1 },
    { "Firefox",             "Dialog",     NULL,                          0,               0,              1,          -1 },	
	{ "Firefox",             NULL,         "Firefox Preferences",         0,               0,              1,          -1 },
	{ "Subl3",               NULL,         "Open File",                   0,               0,              1,          -1 },
	{ "Subl3",               NULL,         "Save File",                   0,               0,              1,          -1 },
	{ "Gcolor2",             NULL,         "gcolor2",                     0,               0,              1,          -1 },
	{  NULL,                 NULL,         "tmux",                        1 << 1,          1,              0,          -1 },
	{  NULL,                 NULL,         "mcfm",                        1 << 1,          1,              0,          -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 = 0;    /* 1 means respect size hints in tiled resizals */

static const Layout layouts[] = {
	/* symbol     arrange function */
	{ "[T]",      tile },    /* first entry is default */
	{ "[M]",      monocle },
	{ "[G]",      gaplessgrid },
	{ "[B]",      bstack },
	{ "[H]",      bstackhoriz },
	{ "[F]",      NULL },    /* no layout function means floating behavior */
	{ NULL,       NULL },
};

/* key definitions */
#define MODKEY Mod4Mask
#define ALTKEY 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_blue1, "-sf", col_gray4, NULL };
static const char *termcmd[]         = { "st", NULL };
static const char *roficmd[]         = { "rofi", "-show", "run", NULL };
static const char *wwwcmd[]          = { "firefox", NULL };
static const char *mailcmd[]         = { "thunderbird", NULL };
static const char *filemgrcmd[]      = { "thunar", NULL };
static const char *editcmd[]         = { "subl3", NULL };
static const char *gimpcmd[]         = { "gimp", NULL };
static const char *volupcmd[]        = { "pamixer", "-i", "5", NULL };
static const char *voldwncmd[]       = { "pamixer", "-d", "5", NULL };
static const char *volmutecmd[]      = { "pamixer", "-t", NULL };
static const char *calccmd[]         = { "libreoffice", "--calc",   NULL };
static const char *doccmd[]          = { "libreoffice", "--writer", NULL };
static const char *exitcmd[]         = { "rofi-logout", NULL };
static const char *jgmenucmd[]       = { "jgmenu", "--config-file=~/.config/jgmenu/jgmouserc", NULL };
static const char *barmenucmd[]      = { "jgmenu", "--config-file=~/.config/jgmenu/jgdwmmenurc", NULL };
static const char *incbrightcmd[]    = { "brillo", "-A", "10", NULL };
static const char *decbrightcmd[]    = { "brillo", "-U", "10", NULL };
static const char *tmuxcmd[]         = { "uxterm", "-title", "tmux", "-e", "tmux", NULL };
static const char *mcfmcmd[]         = { "uxterm", "-title", "mcfm", "-e", "mc", NULL };

static Key keys[] = {
	/* modifier                     key        function        argument */
	{ MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
	{ MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } },
	{ ALTKEY,                       XK_F1,     spawn,          {.v = termcmd } },
	{ ALTKEY,                       XK_F2,     spawn,          {.v = roficmd } },
	{ MODKEY,                       XK_F1,     spawn,          {.v = tmuxcmd } },
	{ MODKEY,                       XK_F2,     spawn,          {.v = mcfmcmd } },
/*                                                                                        */
	{ 0,                            XK_Menu,   spawn,          {.v = filemgrcmd } },
	{ 0,                            XF86XK_AudioRaiseVolume,   spawn,    {.v = volupcmd } },
	{ 0,                            XF86XK_AudioLowerVolume,   spawn,    {.v = voldwncmd } },
	{ 0,                            XF86XK_AudioMute,          spawn,    {.v = volmutecmd } },
	{ 0,                            XF86XK_MonBrightnessDown,  spawn,    {.v = decbrightcmd } },
	{ 0,                            XF86XK_MonBrightnessUp,    spawn,    {.v = incbrightcmd } },
	{ MODKEY|ShiftMask,             XK_q,                      spawn,    {.v = exitcmd } },
	{ MODKEY,                       XF86XK_HomePage,           spawn,    {.v = wwwcmd } },
	{ MODKEY,                       XF86XK_Mail,               spawn,    {.v = mailcmd } },
	{ MODKEY|ControlMask,           XK_l,                      spawn,    {.v = editcmd } },
	{ MODKEY|ControlMask,           XK_g,                      spawn,    {.v = gimpcmd } },
	{ MODKEY|ControlMask,           XK_p,                      spawn,    {.v = calccmd } },
	{ MODKEY|ControlMask,           XK_o,                      spawn,    {.v = doccmd } },
	{ MODKEY|ControlMask,           XK_Print,  spawn,          SHCMD("~/bin/screenshot.sh full") },
	{ ALTKEY|ControlMask,           XK_Print,  spawn,          SHCMD("~/bin/screenshot.sh window") },
/*                                                                                                       */
	{ MODKEY|ControlMask,           XK_b,      togglebar,      {0} },
	{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
	{ ALTKEY,                       XK_Tab,    focusstack,     {.i = +1 } },
	{ ALTKEY|ShiftMask,             XK_Tab,    focusstack,     {.i = -1 } },
	{ MODKEY,                       XK_i,      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_Tab,    view,           {0} },
	{ MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
	{ ALTKEY,                       XK_F4,     killclient,     {0} },
	{ MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} },
	{ MODKEY,                       XK_m,      setlayout,      {.v = &layouts[1]} },
	{ MODKEY,                       XK_g,      setlayout,      {.v = &layouts[2]} },
	{ MODKEY,                       XK_b,      setlayout,      {.v = &layouts[3]} },
	{ MODKEY|ShiftMask,             XK_b,      setlayout,      {.v = &layouts[4]} },
	{ MODKEY,                       XK_f,      setlayout,      {.v = &layouts[5]} },
	{ MODKEY,                       XK_space,  setlayout,      {0} },
	{ MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
	{ ALTKEY|ShiftMask,             XK_space,  cyclelayout,    {.i = -1 } },
	{ ALTKEY,                       XK_space,  cyclelayout,    {.i = +1 } },
/*                                                                                            */
	{ MODKEY,                       XK_Down,   moveresize,     {.v = "0x 25y 0w 0h" } },
	{ MODKEY,                       XK_Up,     moveresize,     {.v = "0x -25y 0w 0h" } },
	{ MODKEY,                       XK_Right,  moveresize,     {.v = "25x 0y 0w 0h" } },
	{ MODKEY,                       XK_Left,   moveresize,     {.v = "-25x 0y 0w 0h" } },
	{ MODKEY|ShiftMask,             XK_Down,   moveresize,     {.v = "0x 0y 0w 25h" } },
	{ MODKEY|ShiftMask,             XK_Up,     moveresize,     {.v = "0x 0y 0w -25h" } },
	{ MODKEY|ShiftMask,             XK_Right,  moveresize,     {.v = "0x 0y 25w 0h" } },
	{ MODKEY|ShiftMask,             XK_Left,   moveresize,     {.v = "0x 0y -25w 0h" } },
	{ MODKEY|ControlMask,           XK_Up,     moveresizeedge, {.v = "t"} },
	{ MODKEY|ControlMask,           XK_Down,   moveresizeedge, {.v = "b"} },
	{ MODKEY|ControlMask,           XK_Left,   moveresizeedge, {.v = "l"} },
	{ MODKEY|ControlMask,           XK_Right,  moveresizeedge, {.v = "r"} },
	{ MODKEY|ControlMask|ShiftMask, XK_Up,     moveresizeedge, {.v = "T"} },
	{ MODKEY|ControlMask|ShiftMask, XK_Down,   moveresizeedge, {.v = "B"} },
	{ MODKEY|ControlMask|ShiftMask, XK_Left,   moveresizeedge, {.v = "L"} },
	{ MODKEY|ControlMask|ShiftMask, XK_Right,  moveresizeedge, {.v = "R"} },
	{ 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_e,      quit,           {0} },
};

/* button definitions */
/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
	/* click                event mask      button          function        argument */
	{ ClkButton,		    0,		        Button1,	    spawn,		    {.v = barmenucmd } },
	{ ClkRootWin,           0,              Button1,        spawn,          {.v = jgmenucmd } },
	{ ClkLtSymbol,          0,              Button1,        setlayout,      {0} },
	{ ClkLtSymbol,          0,              Button3,        setlayout,      {.v = &layouts[2]} },
	{ 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} },
};

3 Likes

I think I’ll leave a link to my current build. dwm with Polybar and a few patches. Works as intended.

All patched manually. I still am yet to master auto patching, though I really don’t mind manually doing this.

1 Like

In the video below, I opted to use the same hacks that:

  1. Removes the names of the apps that are running in bar
  2. makes the complete bar the same color and not that nice shade of blue in the middle

Here is my end result:

Slightly different build -

2021-02-06-05-06-44.png

patches -

dwm-attachaside-20180126-db22360.diff
dwm-awesomebar-20200907-6.2.diff
dwm-focusonclick-20200110-61bb8b2.diff
dwm-gaplessgrid-20160731-56a31dc.diff
dwm-moveresize-20201206-cce77d8.diff
dwm-statusbutton-20180524-c8e9479.diff
dwm-uselessgap-20200719-bb2e722.diff

used the awesomebar patch so that the dwm bar functions like awesome wm bar; all windows shown and windows can be hidden.

pertinent config.h -

/* appearance */
static const unsigned int borderpx  = 4;        /* border pixel of windows */
static const unsigned int gappx     = 0;        /* gaps between windows */
static const unsigned int snap      = 8;       /* snap pixel */
static const int showbar            = 1;        /* 0 means no bar */
static const int topbar             = 1;        /* 0 means bottom bar */
static const char buttonbar[]       = "[=]";
static const int focusonwheel       = 0;
static const char *fonts[]          = { "Roboto Mono:regular:size=10:antialias=true:autohint=true" };
static const char dmenufont[]       = "DejaVu Sans:book:size=10:antialias=true:autohint=true";
static const char col_gray1[]       = "#141414";
static const char col_gray2[]       = "#202020";
static const char col_gray3[]       = "#CCCCCC";
static const char col_gray4[]       = "#DDDDDD";
static const char col_gray5[]       = "#3B3B3B";
static const char col_cyan[]        = "#305773";
static const char *colors[][3]      = {
	/*               fg         bg         border   */
	[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
	[SchemeSel]  = { col_gray4, col_cyan,  col_gray5 },
	[SchemeHid]  = { col_cyan,  col_gray1, col_gray1 },
};
1 Like

Wouldn’t that be more of a hindrance than help? Especially in multiple terminals.

fancybar patch is a pretty sweet patch too.

disclaimer: I didn’t watch the video or haven’t yet, at least.

Looks really nice.

That seems handy.

Also very nice.

1 Like

It can be if you need to hide some windows so an X-app like gimp or Firefox gets all the screen real estate. If you use both tiling and stacking window managers, it standardizes the workflow a bit.

If you only use dwm, just open gimp and firefox on their own tags.

1 Like

Here’s my arch dwm setup… I like the middle space labelled. I have also a heavy use of Nordic colors…

2 Likes

Excellent, yeah I’m just a standard old tiler over here.

Which is what I do. Makes sense for those sort of apps to be on their own tags.

That is nice, I particularly like the tag icons.

@Dobbie03 I started using those (fontawesome glyphs) with bspwm… to my eye they make things look a little less digital and a tad more analog. These days I run pretty much exclusively with dwm. I try to use as few patches as possible.

By way of confession, I, too, use a LukeSmithxyz variant as my terminal (st). Of all the terminals I just like st best. If I ever get off my dead a*s and move to wayland, I’ll probably have to switch to something that likes wayland.

1 Like

Yeah I too use fontawesome as well as pretty much exclusive dwm.

Luke Smith’s st build is particularly solid. I cut my teeth with dwm using his build, then this build was another step and finally many months later I have my own.

I spent Friday with i3wm but only the day. Returned to dwm pretty quick.

Dobbie -

Not really (for me at lest) Since I can simply see on the screen what’s in the current tag, I don’t need to be reminded of it so I don’t have it show up in the title. I DO however, love that the title is now the same color as the tags and status areas.

Yeah it was a good idea, informative video too.

I really did not want to post a video but felt it would would at least let folks know what needs to be changed considering the dwm.c is a rather lengthy file and posting that would be kinda confusing (considering I didn’t bother to document mine, lol)

1 Like

Yeah exactly. No harm done. The more info the merrier. It is a hacking thread after all!

1 Like

@Dobbie03 I know that feeling… i3 is, to my mind, nowhere near dwm in terms of user functionality and useability. I’ve tried it a few times… for me it has been a no-go.

1 Like