Ultra dwm config guide for comfortable work

Dwm is a really fast and efficient window manager. It is based on tiling mode (window size itself is calculated in the best way), but supports other modes (float mode – window size is setting by user). One more thing, it is written in C language and contains about 2000 lines of code. This is quite small in size, you can change the code, make patches and more. But the main and most important settings are in dwm config file.

Let’s start with the basics

First of all, we need dwm source code. It can be obtained from the official website or from the source code repository. If I’m on Debian, I don’t need to go far, I just use the following command to get it:

apt -t unstable source dwm

Learn, How to download a package from testing or unstable repository in Debian

Also, Minimal Xorg installation with dwm on FreeBSD

Upgrade your dwm status bar – Ultra tuning of dwm status bar

The source code will be downloaded to the current directory:

cd dwm-6.1
BUGS  config.def.h  config.mk  debian  drw.c  drw.h  dwm.1  dwm.c  dwm.png  LICENSE  Makefile  README  TODO  transient.c  util.c  util.h

config.def.h is a template file. It has default settings, as in the first launch of dwm. For compilation, it is required that the config file has the name config.h

So, let’s do it

cp config.def.h config.h

If we compile it now, there will be default settings in dwm. So let’s start editing config.h.

Appearance of dwm


At the beginning of the file we can change fonts type and size.

With this option we can change font type and size in status bar:

static const char *fonts[] = {

We can change it in this manner:

static const char *fonts[] = {

We can add multiple fonts, for example supplement this with Japanese VL Gothic font:

static const char *fonts[] = {
     "VL Gothic:size=13",

The next parameter allows us to change dmenu font

static const char dmenufont[] = "monospace:size=10";

Dmenu allows us to run programs by typing their name. It’s Alt + P by default. So, we can change font size and type as in the example above.

Keep in mind, only one font can be defined here.

Window border size and color

Use some tool (W3 Schools HTML Color Picker – requires JavaScript to be enabled) to select a color code. It has html format, like #009eff.

So, the first setting is the border color when window is unfocused:

static const char normbordercolor[] = "#009eff";

It will have a blue color in that case.

And this is the border color when window is focused (When we place mouse pointer on it or when capture a window by Alt + K shortcut):

static const char selbordercolor[]  = "#38b33f";

We can change the border size with the following setting:

static const unsigned int borderpx  = 1;

The border size will be one pixel.

Tags Navigation Colors

Font color of the tag (foreground) in status bar when it is selected (Alt + {number of tag})

static const char selfgcolor[]      = "#ae15ff";

Tag cell color (background), when it is selected (Alt + {number of tag})

static const char selbgcolor[]      = "#000000";

Font color of the tag when it is unfocused

static const char normfgcolor[]     = "#eeeeee";

Tag cell color when it is unfocused

static const char normbgcolor[]     = "#000000";

It means black.

Change tags name and number

Look for this line

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

and change names as you like. For example

static const char *tags[] = { "Home", "Files", "Movies", "Internet", "Music", "Chat" };

In this case, there will be 6 tags.

We can even use UTF icons

static const char *tags[] = { "⌂", "Files", "🎥", "Internet", "♫", "Chat" };

We can switch between them by shortcuts Alt + {Tag number from 1 to 9}

Change current window mode names

I don’t like these default names, so you can find these lines

static const Layout layouts[] = {
	{ "[]=",      tile },    /* Tiling mode */
	{ "><>",      NULL },    /* Floating mode */
	{ "[M]",      monocle },

And change it to more simple

static const Layout layouts[] = {
	{ "T",      tile },    /* first entry is default */
	{ "F",      NULL },    /* no layout function means floating behavior */
	{ "M",      monocle },

It will save space in status bar and become intuitively easier.

Work in dwm

Change the launch rules for a specific application

Here in the class field we need to write the name of the application:

static const Rule rules[] = {
	/* class      instance    title       tags mask     isfloating   monitor */
	{ "Gimp",     NULL,       NULL,       0,            1,           -1 },
	{ "Firefox",  NULL,       NULL,       1 << 3,       0,           -1 },
        { "Transmission",  NULL,       "Transmission",       1 << 1,       0,           -1 },

Then in “tags mask” column specify the tag number in which the application will run. It is numbered starting from zero. For example, 1 << 1 means second tag for Transmission and 1 << 3 means fourth tag for Firefox. If our application runs multiple windows (like Gimp with tools, canvas windows), we should probably use floating mode. So, to do it in “isfloating” column set 1, as with Gimp example.

Add terminal for MODKEY + Shift + Enter shortcut

Find the line that is responsible for calling the terminal

static const char *termcmd[]  = { "x-terminal-emulator", NULL };

And replace it with the terminal you are using. I use urxvt, so

static const char *termcmd[]  = { "urxvt", NULL };

We can also add additional parameters to it by listing them separated by commas.

We can run our terminal by pressing MODKEY (Alt by default) + Shift + Enter, when we have compiled dwm.

Add volume control shortcuts (works both for Alsa and PulseAudio, requires alsa-utils to be installed)

Find these lines

/* commands */
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
static const char *termcmd[]  = { "urxvt", NULL };

And add these lines after

static const char *volumeup[]  = { "amixer", "-D", "default", "sset", "Master", "5%+", "unmute", NULL };
static const char *volumedown[]  = { "amixer", "-D", "default", "sset", "Master", "5%-", "unmute", NULL };

Then find these lines

static Key keys[] = {
	/* modifier                     key        function        argument */
	{ MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
	{ MODKEY|ShiftMask,             XK_Return, spawn,          {.v = termcmd } },

And paste these lines after

	{ MODKEY,                       0x5d,      spawn,          {.v = volumeup } },
	{ MODKEY,                       0x5b,      spawn,          {.v = volumedown } },

After compilation, we can decrease volume level by -5% by MODKEY + [ shortcut and increase by 5% by MODKEY + ]. MODKEY is Alt by default.

We can change the key by editing “key” column. There should be key code. Use the following command to get key code (required kbd package to be installed):

showkey -a

The key code is placed in the third column of showkey output.

Bind scrot to shortcut for taking screenshots

Be sure that scrot package installed in your system. It is a simplest tool for taking screenshots in Linux.

Add following lines in keys[] array (as in examples above):

	{ ControlMask,    		XK_Print,  spawn,	   SHCMD("sleep 1s;scrot --focused ~/Screenshots/%Y-%m-%d-%H:%M:%S.jpg") },
	{ ShiftMask,	  		XK_Print,  spawn,	   SHCMD("sleep 1s;scrot --select ~/Screenshots/%Y-%m-%d-%H:%M:%S.jpg") },

Don’t forget to change the screenshots directory. Then compile it. Now we can select a screenshot area by pressing Shift + Print Screen and grab focused window by pressing Ctrl + Print Screen.

There is more info about scrot: Scrot: improve your screenshot compression with ffmpeg

Updated: May 26, 2019 — 11:50 am