dwm: The dynamic window manager
23-Oct-2021 (last update 02-Nov-2024)
A window manager is a software that can manage the layout and appearance of every window spawned in your desktop, most people confuse them with desktop enviroments, which aren’t the same since a desktop enviroment is more like an ecosystem, they come with a more ‘complete’ set of tools, like a basic web browser, a terminal emulator or a graphical calculator, an example of desktop enviroment would be gnome, xfce or kde plasma; instead a window manager is only the program that manages the windows spawned, although there are window managers that come with a little more, like docks or taskbars (openbox for example).
In my case I use dwm, which is a window manager written in C developed by suckless software. The most relevant thing of this window manager is that out of the box it comes with the most basic functionallity, and if you want to extend it you need to patch it (I explain patching later).
By default dwm comes with 9 workspaces, in which you can open as many windows as you please; to spawn a new window for example a web browser you need to assign it a keybinding or use an application launcher like dmenu
Installing dwm
Requisites
- GNU/Linux or BSD based operating system
- A C library and a C compiler
- make utility installed
- X server installed
- dwm source code
As you can see above you can only install dwm on GNU/Linux or BSD based distros, unfortunally dwm is not available for Windows users and I’m not sure if there is an alternative.
Steps
In order to install dwm download the source code from suckless.org/dwm, you can clone the repo from git.suckless.org/dwm or download it as a tar file.
After you obtain the source code navigate to the root folder of the source code and execute the following command
$ sudo make install
after that you can log out of you user account, if you use a display
manager, select dwm as window manager on it and log back in, if you
don’t use a display manager, you need to edit your .xinitrc file located
at your home folder, so that when you start Xorg dwm gets launched, you
do this by adding exec dwm
to the end of the .xinitrc
file, its important that you add it to the end of the file.
exec dwm
Then you can start the X server by executing startx
on a tty and
dwm should start without any problems.
This is what vanilla dwm looks like:
Customizing dwm
Setting a wallpaper
Before getting into dwm configuration, let’s add a wallpaper to make things look a little bit nicer. You can set a wallpaper from different ways, the simpler for me is installing feh and the executing the following command
$ feh --bg-fill <image>
you can also avoid setting –bg-fill and chossing other feh options to set the wallpaper (read man feh).
Then add .fehbg &
to your .xinitrc so the wallpaper gets loaded when Xorg starts, it is important
that you add it before dwm gets executed, otherwise it will never be ran
$HOME/.fehbg &
exec dwm
A graphical way of setting a wallpaper is with nitrogen, just install nitrogen open it with dmenu (MOD+p by default), include the folder where you have your wallpaper, select the image you want and the apply. To make changes persistent on every startup add this to you .xinirc file
nitrogen --restore
exec dwm
dwm configuration
Basically you configure dwm by editing its source code, there is a C header file, named
config.h
in the root folder of dwm, if you open it with a text editor you can see a
lot of variables, for example the line static const int topbar = 0
defines a variable named topbar which you can set to 1 or 0, to select
if the status bar should spawn in the top or bottom of the screen respectively.
You can also change the MOD key (by default its left alt), I like to remap
mine to left Super (windows key).
After every change you make to the source code you need to recompile dwm.
Show information on the status bar
dwm by default won’t show any information on the status bar, this is done by using the xsetroot utility, which sets the value of WM_NAME enviroment variable, the content of this variable is automatically displayed by dwm on the right side of the statusbar. Lets assume you want to set the clock and date on the status bar, well you could accomplish this by executing the following command
$ xsetroot -iname $(date)
and all the output of the command date
would be stored on the WM_NAME variable
causing dwm to print the date on the statusbar, this
makes dwm status bar highly scriptable, in fact there are a ton of status
bar implementations, the one that I use is called
dwmblocks and its also
written in C and the configuration its pretty much the same as dwm, in
order to get information you need to have scripts that prints the
desired data to stdout, then you can include them on the config.h of
dwmblocks. It is important that the scripts are on your user’s PATH, otherwise
it won’t work.
Getting emoji support on dwm
dwm by default doesn’t come with emoji support, if you want to render an emoji in the status bar, it’s going to either show it as a box or in the worst case crash.
In order to get emoji support first make sure you have installed libxft
,
then you need to get a font with emoji support, I’m using JoyPixels® font
you can also use Google’s noto font,
or any other font that comes with emoji support, then open dwm config.def.h
and
append to the fonts array the name of the font you want to use as fallback for the first font,
since the emojis are not being printed because the font used doesn’t include emojis, my
config looks like this:
static const char *fonts[] = { "Source Code Pro:style=Regular:size=9",
"JoyPixels:style=Regular:size=8",
"DejaVu Sans" };
I’ve also added DejaVu Sans
to the fonts array because, sometimes, the emojis where being displayed
with a little box or square next to them, this was a quick solution.
After you setup the font you need to remove or comment a chunk of code
from drw.c, between lines 136-150 there is a function named iscol
, you
need to remove it or comment it, since this causes dwm to crash.
/* Do not allow using color fonts. This is a workaround for a BadLength
* error from Xft with color glyphs. Modelled on the Xterm workaround. See
* https://bugzilla.redhat.com/show_bug.cgi?id=1498269
* https://lists.suckless.org/dev/1701/30932.html
* https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
* and lots more all over the internet.
*/
FcBool iscol;
if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
XftFontClose(drw->dpy, xfont);
return NULL;
}
Finally you can recompile dwm and, if everything went fine, you will get emoji support.
Patching dwm
Since dwm is a simple program than doesn’t include much features, if you want to extend it, for example by adding a systray to the status bar, you need to patch dwm. To do this first you need to download the patch from suckless.org/patches, then make sure you got it ‘patch’ installed, although I think it comes with most linux distributions by default nowdays.
To apply a patch navigate to dwm’s root folder and execute this command
$ patch -p1 < <file.diff>
being file.diff
the patch file downloaded previoulsy of course.
If you never patched dwm before then probably no errors would be reported, but if you already have applied a ton of patches, (or sometimes just a couple) then probably you would get a HUNK ## FAILED, in this case you need to get your hands dirty, and manually patch all the files that failed, you do this by opening the files with .rej extension (short for rejected), and the corresponding file to be patched, for example dwm.c and dwm.c.rej, and then you add all the chunks of code from the rejected file into the corresponding place in the non rejected file, you know where you should put the chunks of code because in the rej file you can see at the start of every chunk there is a ‘@@’ followed by a number of line; also lines starting with plus means add, and minus means delete, if I’m not clear you should google how to use diff and patch to modify a file.
More screenshots
Debugging 6502 emulator with dwm, vim and tmux
Floating window manager?
Useful links
- What is a window manager?
- Make sure to check the suckless webiste
- suckless dwm website
- X server man page
- patch man page