__       _______ _______ _______ ___ _______ ___     _______ _______
 .-----.--.--.-----.-----|  |_    |   _   |   _   |       |   |   _   |   |   |   _   |   _   |
 |  _  |  |  |  -__|__ --|   _|   |.  1   |.  l   |.|   | |.  |.  1___|.  |   |.  1___|   1___|
 |___  |_____|_____|_____|____|   |.  _   |.  _   `-|.  |-|.  |.  |___|.  |___|.  __)_|____   |
 |_____|                          |:  |   |:  |   | |:  | |:  |:  1   |:  1   |:  1   |:  1   |
                                  |::.|:. |::.|:. | |::.| |::.|::.. . |::.. . |::.. . |::.. . |
                                  `--- ---`--- ---' `---' `---`-------`-------`-------`-------'

How to Install, Customize and Backup Suckless Tools

By Ronnie Nissan at April 18, 2020


The suckless tools, especially dwm, st and dmenu, are some amazing pieces of software, that allow a great flexibility while being minimal. But they come at a cost, yes, Libra software is free as both in freedom and as in beer (most) of time), but you should make an effort to be able to use it, and that effort (cost) is much needed when it comes to the sucklees tools.

I used dwm, st and dmenu about a year ago, but I had no idea how to manage and backup them, I didn't know a lot about customizing (patching) them, but recently I started learning C programming language, and so I decided to use all three, as I will have to edit the source code to make any changes and so this will help me in my endeavor of learning C.

The reason I am making this tutorial is to help you get started with using dwm, st and dmenu too. This tutorial is my own personal experience and knowledge and has no connection to the guys at suckless, nor it is the best how-to guide.

This tutorial will assume you have a basic knowledge in Linux and you are able to install packages though your distros package manager and solve dependencies, and that you use xinit to login to your xorg-session.


To install any of the above three, you'll need to have some libraries and git installed in your system, you can install them as following;

On Void Linux:

sudo xbps-install -S git make libX11-devel libXinerama-devel

On Debian and Debian-based distros:

sudo apt-get install build-essential libx11-dev libxinerama-dev sharutils

And on Arch and Arch-based distros:

sudo pacman -S git make libX11-devel libXinerama-devel


Clone dwm from suckless.org

git clone https://git.suckless.org/dwm
cd dwm/
sudo make install

Then all that's left is that you put the following to your .xinitrc then start x with startx (nice!).

exec dwm

This will give you an untouched dwm experience like the guys at suckless intended it.


Clone st from suckless.org

git clone https://git.suckless.org/st
cd st/
sudo make install

And this will install st, unmodified, on your system. Just note that st doesn't have a .desktop file by default, which means you will not find it in menus (like dmenu) whoever, st it is the default terminal in dwm and it is bound to ALT + Shift + Return.


Clone dmenu from suckless.org

git clone https://git.suckless.org/dmenu
cd st/
sudo make install

Now dmenu is installed on your system. In dwm, alt + p is bound to launching dmenu.


By now you should have a working (in the suckless philosophy way) system, but maybe you want to edit some colors, add some features through patching those programs to make them even more usable, or just more pleasing to look at.

NOTE: It is recommended that you make a copy of config.def.h file and name it config.h and make your edits to this file, so that when you update dwm for example you get the new config.def.h it will not overwrite your modifications, whoever I don't do that, I edit config.def.h and config.h is generated automatically when you compile and install. this way when a patch edited config.def.h, I can just delete config.h and recompile


To edit dwm, you'll have to cd into the dwm directory and edit config.def.h, remember to remove the config.h file before recompiling (see note above). and here I'll explain some parts of the config file.

Font and Color-scheme

In lines 8 and 9 you can set the font, and font size of dwm, and also dmenu if you don't want to edit your dmenu installation and launch it though the dwm defined flags on line 59.

From line 10 to line 19 in your config.h file, you'll see the following

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 *colors[][3]      = {
	/*               fg         bg         border   */
	[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
	[SchemeSel]  = { col_gray4, col_cyan,  col_cyan  },

In the lines from 10 to 15 you'll see some constants of type character defined. they are six colors, which you can change to whatever you like, you can also change the names of the constants for example:

static const char normalbg[]       = "#0ff000"

Then on line 17 and 18 we are setting the defined constants to the element we want which are SchemeNorm and Schemesel from the *colors constant, the first color is the foreground (fg) second is the background (bg) and the third is border color. Edit those to your liking then recompile, install and exit and log back into dwm to see your changes.

The rules

From line 30 to 31 you'll see some rules set for gimp and Firefox

/* class      instance    title       tags mask     isfloating   monitor */
{ "Gimp",     NULL,       NULL,       0,            1,           -1 },
{ "Firefox",  NULL,       NULL,       1 << 8,       0,           -1 },

You can rules for over programs and remove the ones set as you like, what you need to know is, the class of the program using xprop. And writing it under “class”, keeping both “instance” and “title” as NULL (most of the time) if you set “isfloating” to 1, the program will spawn in floating mode, and under “monitor” you set which monitor the program will spawn on.

It's the “tags mask” that is a bit tricky. but it is easy ones you know what you are doing. they are bit-wise operators (which I myself don't fully understand to be honest) but if all you want to do is spawn Firefox on the ninth tag (default behavior) you'll have to set tag mask to “1 « 8” which means 1 shifted to the right by 8, which makes it 9. so the tags by default are “000000001”, when the 1 is in the rightmost position (the ninth from left to right) you are on tag 1, so what “1 « 8” means is to put the “1” in the leftmost position 100000000 (first position from left), which is tag nine.

If you want Emacs for example to open on tag 3 and in floating mode you'll add this line to the above code:

{ "Emacs",     NULL,       NULL,       1 << 2,            1,           -1 },

Which translates to “000000100”. If you want to learn more about tag masks, check "How does a tag-mask work?" over at suckless.org (in links below).


I will not cover key bindings because I use sxhkd for custom keybindings, but if you want to use dwm key daemon or you just want to edit a few of the default a look at the config from line 46 to line 96 help you as it is self explanatory. if you want to change the mod key from alt to super key, you can edit line 47 and it from Mod1Mask to Mod4Mask. This is more than enough to get you a customized dwm and you can start living in it from this point, but if you want to learn how to patch it, go to the “Patching” section of this page.


The simple Terminal is amazing, fast and has the best font rendering (second only to Alacritty) in my opinion. but it lacks some basic functionality by default which I'll address under the “Patching” section. but for Just changing some of the default bindings and color schemes, you'll do the same as you did with dwm, go to the st directory, and edit the config.def.h file, remove the config.h file and recompile.

Font and Padding

To edit the font and the padding you'll have to edit line 8 and 9, to set the font to Hack and size to 14, and set padding to 8, you'll do the following:

static char *font = "Hack:pixelsize=14:antialias=true:autohint=true"
static int borderpx = 8;


To change st's default color-scheme you'll have to edit Lines 86 to 112:

/* Terminal colors (16 first used in escape sequence) */
static const char *colorname[] = {
	/* 8 normal colors */

	/* 8 bright colors */

	[255] = 0,

	/* more colors can be added after 255 to use with DefaultXX */

Cursor Shape

St have four cursor shapes defined by default:

 * Default shape of cursor
 * 2: Block ("█")
 * 4: Underline ("_")
 * 6: Bar ("|")
 * 7: Snowman ("☃")

To change the cursor to any of the above you'll edited line 131 and set it to the number corresponding to the shape you want.

static unsigned int cursorshape = 2;

This is the basic customization that you can do to st, to make it more pleasing to look it.


You customize dmenu the same way you did st and dwm, by editing the config.def.h, removing config.h and recompiling. dmenu is a flexible and simple program that you can do a lot with, I use it to set my wallpaper, change my monitor layout, as a power-menu etc. You can pipe things into dmenu and paste the output to Stout. which makes it extensible though scripting.

Note! please remember that if you want to use your own build of dmenu, you'll have to remove some things from dwm, the things to be removed from config.def.h of dwm are the following; In line 59, everything between <> should be removed

static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, <"-fn", dmenufont, "-nb", col_gray1,
                                  "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4,> NULL };

Font and color-scheme

To change the font on dmenu you should edit line 7 and set it to the font that you want.


To change the color-scheme, it's the same as in dwm, but here we sit the colors inside the *colors constant directly.

[SchemeNorm] = { "#bbbbbb", "#222222" },
[SchemeSel] = { "#eeeeee", "#005577" },
[SchemeOut] = { "#000000", "#00ffff" },

First one is the foreground and the second one is the background. first line is for the Normal entries and second line for the selected entries. If you want to watch a good video about dmenu, I recommend that you watching Luke Smith's video on it.


Patching is how you extend the suckless tools with features they lack out of the box that either make them more usable or enhance the look and feel of them, Like adding the ability of scroll back in st and gaps in dwm. to apply a patch you must go to suckless.org first. download the patch you want to apply to the source-code directory of the software you want to apply it to. then you'll do the following.

sudo make clean
git remove config.h
git branch <name of the patch>.def
git checkout <name of the new branch>
patch -p1 < <name of the patch>

At this point, if all the hunks were successful, you will do:

git status #and check which files were modified, then do
git add <names of the modified files>
git commit -m <enter a of what you are committing here>
git checkout master
git merge <name of the new branch>
sudo make install

If one or more hunks fails, you'll have to look into the terminal to see which file (or files) was it that the hunks failed to apply to, and you'll see inside the source code you'll have a file called, ..rej so now all you have to do is, open the .rej file in your favorite text editor, look for the lines that have “-” (remove) and “+” (add) right to them, those are the lines you have to remove and add. then you'll do the above steps.

In case you want to remove a patch you've applied you have to does

patch -R < <name of the patch>.def

If you want to learn more about patches check out the Hacking page from suckless.org and you can also watch DistroTube's video on Patching dmenu.


When you customize any of the suckless tools to your liking, you'll know it is not as easy as editing a config file, especially after you patch them. So keeping a backup of them is not as easy as saving a dotfile to a git repository and linking it to .config/name-of-program. In this section I'll show you the steps to make a backup of your suckless tools while still having the ability to update them when a new version comes out (which doesn't happen that often).

First of all you have to be in the directory of the program you want to make a backup of. then you'll rename the remote of the git repository from origin to upstream.

git remote rename origin upstream

Then you'll go to github.com (or gitlab) and make a new repository, call it the same as the program you are backing up for convenience. then copy the repository's URL and type:

git add remote origin <the repository's url>

Now if you type:

git remote -v

You'll see that you have two remotes called upstream (pointing to suckless.org) and one called origin (pointing to your repository). now all that's left is that you push your build to the master branch of your repository, to do that you type:

git push origin master

If the guys at suckless updated the program, all you'll have to do is, go to that programs directory, and run the following:

git pull upstream master

I think by now you can get around using the suckless tools with ease, customize them and back them up. which is really amazing because the suckless tools are amazing. Later I'll be posting more articles explaining how to customize dwm's bar and how to use sxhkd as your key daemon.

I really hope you enjoyed this read and that it was usefully to you.


How Tag Masks Work Hacking on Suckless