The Great dwm & Suckless Hacking Thread

I will, yes. I, also, plan on including the config.h for my slstatus, conkybar as well as a few other items. For example, I have built another yad script for systems monitor access…

Systems-monitoring-yad

Top again @manyroads

Nothing new on my side, just the same old boring – but functional – suckless setup with slstatus.

 */
static const struct arg args[] = {
	/* function format          argument */
	{ battery_perc, " 🔋%s%% ",	"BAT0" },
	{ battery_remaining, "⌁ %s ",	"BAT0" },
	{ load_avg, "|  %s ",		"NULL" },
	{ disk_free, "|  %s ",     	"/home/" },
	{ ram_used, "|  %s ",     	"NULL" },
	{ cpu_perc, "|  %s%% ",     	"NULL" },
			      
	{ datetime, "| %s ",         	" %a %F |  %T" },
};
4 Likes

Another great job manyroads I like PackRat have interest the yad script too. Will hunt it down just have so much going on at the moment between house reno’s and working on two systems.
Thanks again mate…

Top @Beast

1 Like

Enjoy @KoO It is all posted here: Dwm & i3wm Tricks & cleanup

1 Like

Damn it, I have been wanting to use Polybar with my very heavily patched version of dwm. I was manually patching the anybar patch got 90% of the way through and just couldn’t go any further.

My dwm.c file is just beyond the anybar patch. I probably need to start from scratch but I really can’t be bothered.

@Dobbie03 FWIW… I found anybar quite difficult and just decided to make slstatus work for me. I wish I could have better eye candy with slstatus, although I find my new version acceptable and light. Hooray for glyphs. :wink:

1 Like

Yeah it’s only because my current set up is already so heavily patched. I have successfully used anybar before on other dwm setups but I prefer this current one I am using so I am really wanting to get this added.

Yeah I just use a simple conky config instead of slstatus etc. Every once in a while I will use slstatus but generally my conky is enough.

1 Like

@Dobbie03 FWIW: Here’s my most recent slstatus… I use fontawesome and nerd-fonts for the glyphs.

static const struct arg args[] = {
        /* function  format          argument */
        { cpu_perc,  	"     CPU %s%% " },
        { battery_perc, "   %s%% ","BAT0" },
        { ram_perc, 	"   %s%% " },
        { disk_used,	"   %sB ","/" },
        { temp, "  %s\u00b0C ", "/sys/class/thermal/thermal_zone4/temp" },
        { wifi_perc,	"   %s%% ","wlan0"  },
        { datetime,  	" %s", "  %a. %d %b. %Y    %H:%M  " },
};


3 Likes

For those who want to gain access to ‘pretty darn good’ articles on getting started with dwm, may I suggest the following reading list (aside from the obvious items on suckless and the archwiki):

https://ratfactor.com/dwm

https://linuxgoodies.braintidbits.com/review_dwm.html

https://srobb.net/dwm.html

https://fediverse.blog/~/Cmm/installing-suckless's-dwm-how-it-works-and-how-to-install-my-build

2 Likes

Top again @manyroads

Looking good, thanks for sharing.

1 Like

So I have spent the last few hours building from scratch a dwm build with polybar. I have a couple of issues that hopefully someone here maybe able to assist with to solve.

Quirk Number One:

I have a key bind of mod1mask + m to launch st with ncmpcpp on my secondary monitor.

What happens when I use that keybind, the tags switch to the tag that st is defined to without focusing the second monitor with ncmpcpp

Relevent Information:

Rules array:

Keybind:

{ MODKEY, XK_m, spawn, SHCMD("st -c ncmpcpp -e ncmpcpp") },

Quirk Number Two:

When I open a image to view, rather than focusing sxiv which defined to open on the same tag as Thunar, 5, it jumps to and focuses Firefox.

Does anyone have any ideas? These are the patches I have used:

EDIT

I fixed both issues with this custom patch.

I am very happy with the result.

2 Likes

Oh, loads of work in there @Dobbie03

Yeah I think it was about 4 hours in total, the first couple of patches patched nicely with git apply the rest I had to manually patch. It was a lot of fun :smiley:

1 Like

lol, big fun in there !

1 Like

dwm with a few patches, jgmenu, near monochrome color scheme:

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

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

/* appearance */
static const unsigned int borderpx  = 4;        /* border pixel of windows */
static const unsigned int snap      = 32;       /* snap pixel */
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 *fonts[]          = { "roboto mono:size=10" };
static const char dmenufont[]       = "roboto:size=10";
static const char col_gray1[]       = "#191919";
static const char col_gray2[]       = "#393939";
static const char col_gray3[]       = "#cdcdcd";
static const char col_gray4[]       = "#ededed";
static const char col_cyan[]        = "#2C3339";
static const char *colors[][3]      = {
	/*               fg         bg         border   */
	[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
	[SchemeSel]  = { col_gray4, col_cyan,  col_gray2 },
};

static const char *const autostart[] = {
	"slstatus", NULL,
	NULL /* terminate */
};

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

static const Rule rules[] = {
	/* xprop(1):
	 *	WM_CLASS(STRING) = instance, class
	 *	WM_NAME(STRING) = title
	 */
	/* class      instance    title       tags mask     isfloating   monitor */
	{ "XCalc",       NULL,    NULL,        0,            1,           -1 },
	{ "Galculator",  NULL,    NULL,        0,            1,           -1 },
	{ "feh",         NULL,    NULL,        0,            1,           -1 },
	{ "sxiv",        NULL,    NULL,        0,            1,           -1 },
	{ "Gcolor2",     NULL,    NULL,        0,            1,           -1 },
	{ "Audacious",   NULL,    NULL,        1 << 8,       0,           -1 },
	{ "Asunder",     NULL,    NULL,        1 << 8,       0,           -1 },
	{ "Gimp",        NULL,    NULL,        1 << 7,       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 = 0;    /* 1 means respect size hints in tiled resizals */
static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */

static const Layout layouts[] = {
	/* symbol     arrange function */
	{ "[]=",      tile },    /* first entry is default */
	{ "><>",      NULL },    /* no layout function means floating behavior */
	{ "[M]",      monocle },
};

/* 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_cyan, "-sf", col_gray4, NULL };
static const char *termcmd[]     = { "st", NULL };
static const char *rxvtcmd[]     = { "urxvt", NULL };
static const char *roficmd[]     = { "rofi", "-show", "run", NULL };
static const char *fmcmd[]       = { "urxvt", "-e", "mc", NULL };
static const char *wwwcmd[]      = { "firefox", NULL };
static const char *editcmd[]     = { "geany", NULL };
static const char *volupcmd[]    = { "pamixer", "-i", "5", NULL };
static const char *voldncmd[]    = { "pamixer", "-d", "5", NULL };
static const char *volmutecmd[]  = { "pamixer", "-t", 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 = rxvtcmd } },
	{ ALTKEY,                       XK_F2,     spawn,          {.v = roficmd } },
	{ 0,                            XF86XK_HomePage,           spawn,    {.v = wwwcmd } },
	{ 0,                            XF86XK_AudioRaiseVolume,   spawn,    {.v = volupcmd } },
	{ 0,                            XF86XK_AudioLowerVolume,   spawn,    {.v = voldncmd } },
	{ 0,                            XF86XK_AudioMute,          spawn,    {.v = volmutecmd } },
	{ 0,                            XK_Menu,   spawn,          {.v = fmcmd } },
	{ MODKEY|ControlMask,           XK_l,      spawn,          {.v = editcmd } },
	{ MODKEY|ShiftMask,             XK_Print,  spawn,          SHCMD("import -window root $HOME/images/$(date '+%Y-%m-%d-%T')-screenshot.png") },
	{ MODKEY|ControlMask,           XK_Print,  spawn,          SHCMD("scrot 'scrot-%F-%s_$wx$h.png' -e 'mv $f ~/images/'") },
	{ MODKEY|ShiftMask,             XK_q,      spawn,          SHCMD("rofi_run -l") },
	{ MODKEY,                       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_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_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 */
	{ 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,            0,              Button2,        spawn,          SHCMD("jgmenu --config-file=/home/doug/.config/jgmenu/jgbarmenurc") },
	{ ClkTagBar,            MODKEY,         Button1,        tag,            {0} },
	{ ClkTagBar,            MODKEY,         Button3,        toggletag,      {0} },
};

2 Likes

Looks really good, do you use jgmenu a lot? If dmenu wasn’t a thing I suppose I would use jgmenu.

I don’t use menus much at all. Most of what I need to do is set up as a key binding.

I added jgmenu to this install because I was tweaking the mouse section of config.h. It was easy enough to add a mouse click for a pull down menu.

I also have key bindings for dmenu (kept the default) and rofi. Lately, I find myself using dmenu most often.

Need to get more creative and do some pipe menus for jgmenu and get more use out of it.

1 Like