repos/kloeckner.com.ar

Backup of part of my webpage
Commits Files Refs README LICENSE
blog/dwm-config/dwm-config.md (239 lines)

%% title: "dwm: The dynamic window manager" date: "23-Oct-2021" %%

dwm: The dynamic window manager

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

Screenshot

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:

Vanilla dwm

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

Debugging 6502 emulator  

Floating window manager?

Floating show

Useful links

   1 %%
   2 title: "dwm: The dynamic window manager"
   3 date: "23-Oct-2021"
   4 %%
   5 
   6 # dwm: The dynamic window manager
   7 
   8 A window manager is a software that can manage the layout and appearance
   9 of every window spawned in your desktop, most people confuse them with
  10 desktop enviroments, which aren't the same since a desktop enviroment is
  11 more like an ecosystem, they come with a more 'complete' set of tools,
  12 like a basic web browser, a terminal emulator or a graphical calculator, an example
  13 of desktop enviroment would be gnome, xfce or kde plasma; instead a
  14 window manager is only the program that manages the windows spawned,
  15 although there are window managers that come with a little more, like
  16 docks or taskbars (openbox for example).
  17 
  18 In my case I use dwm, which is a window manager written in C developed
  19 by suckless software. The most relevant thing of this window manager is
  20 that out of the box it comes with the most basic functionallity, and if
  21 you want to extend it you need to patch it (I explain patching later).
  22 
  23 By default dwm comes with 9 workspaces, in which you can open as many
  24 windows as you please; to spawn a new window for example a web browser
  25 you need to assign it a keybinding or use an application launcher like
  26 [dmenu](https://tools.suckless.org/dmenu/)
  27 
  28 [![Screenshot](screenshot.jpeg)](screenshot.png "Screenshot of my dwm build")
  29 
  30 ## Installing dwm
  31 
  32 ### Requisites
  33 
  34 - GNU/Linux or BSD based operating system
  35 - A C library and a C compiler
  36 - make utility installed
  37 - X server installed
  38 - dwm source code
  39 
  40 As you can see above you can only install dwm on GNU/Linux or BSD based
  41 distros, unfortunally dwm is not available for Windows users and I'm not
  42 sure if there is an alternative.
  43 
  44 ### Steps
  45 
  46 In order to install dwm download the source code from [suckless.org/dwm](https://dwm.suckless.org/),
  47 you can clone the repo from [git.suckless.org/dwm](https://git.suckless.org/dwm) or
  48 download it as a tar file.
  49 
  50 After you obtain the source code navigate to the root folder
  51 of the source code and execute the following command
  52 
  53 ```console
  54 $ sudo make install
  55 ```
  56 
  57 after that you can log out of you user account, if you use a display
  58 manager, select dwm as window manager on it and log back in, if you
  59 don't use a display manager, you need to edit your .xinitrc file located
  60 at your home folder, so that when you start Xorg dwm gets launched, you
  61 do this by adding `exec dwm` to the end of the .xinitrc
  62 file, its *important* that you add it to the end of the file.
  63 
  64 ```console
  65 exec dwm
  66 ```
  67 
  68 Then you can start the X server by executing `startx` on a tty and
  69 dwm should start without any problems.
  70 
  71 This is what vanilla dwm looks like:
  72 
  73 [![Vanilla dwm](vanilla.jpeg)](vanilla.png "Vanilla dwm")
  74 
  75 ## Customizing dwm
  76 
  77 ### Setting a wallpaper
  78 
  79 Before getting into dwm configuration, let's add a wallpaper to make things look
  80 a little bit nicer. You can set a wallpaper from different ways, the simpler for
  81 me is installing feh and the executing the following command
  82 
  83 ```console
  84 $ feh --bg-fill <image>
  85 ```
  86 
  87 you can also avoid setting --bg-fill and chossing other feh options to set the wallpaper
  88 (read man feh).
  89 
  90 Then add `.fehbg &` to your .xinitrc so the wallpaper gets loaded when Xorg starts, it is important
  91 that you add it before dwm gets executed, otherwise it will never be ran
  92 
  93 ```console
  94 $HOME/.fehbg &
  95 
  96 exec dwm
  97 ```
  98 
  99 A graphical way of setting a wallpaper is with nitrogen, just install nitrogen open it
 100 with dmenu (MOD+p by default), include the folder where you have your wallpaper, select the
 101 image you want and the apply. To make changes persistent on every startup
 102 add this to you .xinirc file
 103 
 104 ```console
 105 nitrogen --restore
 106 
 107 exec dwm
 108 ```
 109 ### dwm configuration
 110 
 111 Basically you configure dwm by editing its source code, there is a C header file, named
 112 [config.h](https://github.com/mjkoeckner/dotfiles/blob/master/.config/dwm/config.def.h)
 113 in the root folder of dwm, if you open it with a text editor you can see a
 114 lot of variables, for example the line `static const int topbar = 0`
 115 defines a variable named topbar which you can set to 1 or 0, to select
 116 if the status bar should spawn in the top or bottom of the screen respectively.
 117 You can also change the MOD key (by default its left alt), I like to remap
 118 mine to left Super (windows key).
 119 
 120 After every change you make to the source code you need to *recompile dwm*.
 121 
 122 
 123 #### Show information on the status bar
 124 
 125 dwm by default won't show any information on the status bar, this is
 126 done by using the xsetroot utility, which sets the value of WM\_NAME enviroment
 127 variable, the content of this variable is automatically displayed by dwm on the
 128 right side of the statusbar. Lets assume you want to set the clock and date
 129 on the status bar, well you could accomplish this by executing the following command
 130 
 131 ```console
 132 $ xsetroot -iname $(date)
 133 ```
 134 
 135 and all the output of the command `date` would be stored on the WM\_NAME variable
 136 causing dwm to print the date on the statusbar, this
 137 makes dwm status bar highly scriptable, in fact there are a ton of status
 138 bar implementations, the one that I use is called
 139 [dwmblocks](https://github.com/torrinfail/dwmblocks) and its also
 140 written in C and the configuration its pretty much the same as dwm, in
 141 order to get information you need to have scripts that prints the
 142 desired data to stdout, then you can include them on the config.h of
 143 dwmblocks. It is important that the scripts are on your user's PATH, otherwise
 144 it won't work.
 145 
 146 #### Getting emoji support on dwm
 147 
 148 dwm by default doesn't come with emoji support, if you want to render
 149 an emoji in the status bar, it's going to either show it as a box or in
 150 the worst case crash.
 151 
 152 In order to get emoji support first make sure you have installed `libxft`,
 153 then you need to get a font with emoji support, I'm using [JoyPixels® font](https://www.joypixels.com/)
 154 you can also use [Google's noto font](https://fonts.google.com/noto),
 155 or any other font that comes with emoji support, then open dwm `config.def.h` and
 156 append to the fonts array the name of the font you want to use as fallback for the first font,
 157 since the emojis are not being printed because the font used doesn't include emojis, my
 158 config looks like this:
 159 
 160 ```c
 161 static const char *fonts[] = { "Source Code Pro:style=Regular:size=9",
 162                                 "JoyPixels:style=Regular:size=8",
 163                                  "DejaVu Sans" };
 164 ```
 165 
 166 I've also added `DejaVu Sans` to the fonts array because, sometimes, the emojis where being displayed
 167 with a little box or square next to them, this was a quick solution.
 168 
 169 After you setup the font you need to remove or comment a chunk of code
 170 from drw.c, between lines 136-150 there is a function named `iscol`, you
 171 need to remove it or comment it, since this causes dwm to crash.
 172 
 173 ```c
 174 /* Do not allow using color fonts. This is a workaround for a BadLength
 175  * error from Xft with color glyphs. Modelled on the Xterm workaround. See
 176  * https://bugzilla.redhat.com/show_bug.cgi?id=1498269
 177  * https://lists.suckless.org/dev/1701/30932.html
 178  * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=916349
 179  * and lots more all over the internet.
 180  */
 181 FcBool iscol;
 182 if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
 183     XftFontClose(drw->dpy, xfont);
 184     return NULL;
 185 }
 186 ```
 187 
 188 Finally you can recompile dwm and, if everything went fine, you will get emoji support.
 189 
 190 #### Patching dwm
 191 
 192 Since dwm is a simple program than doesn't include much features, if
 193 you want to extend it, for example by adding a
 194 [systray](https://dwm.suckless.org/patches/systray/) to the status bar,
 195 you need to patch dwm. To do this first you need to download the patch
 196 from [suckless.org/patches](https://dwm.suckless.org/patches/), then
 197 make sure you got it 'patch' installed, although I think it comes with
 198 most linux distributions by default nowdays.
 199 
 200 To apply a patch navigate to dwm's root folder and execute this command
 201 
 202 ```console
 203 $ patch -p1 < <file.diff>
 204 ```
 205 
 206 being `file.diff` the patch file downloaded previoulsy of course.
 207 
 208 If you never patched dwm before then probably no errors would be
 209 reported, but if you already have applied a ton of patches, (or sometimes just a couple)
 210 then probably you would get a HUNK \## FAILED, in this case you need to get your hands
 211 dirty, and manually patch all the files that failed, you do this by
 212 opening the files with .rej extension (short for rejected), and the
 213 corresponding file to be patched, for example dwm.c and dwm.c.rej, and
 214 then you add all the chunks of code from the rejected file into the
 215 corresponding place in the non rejected file, you know where you should
 216 put the chunks of code because in the rej file you can see at the start
 217 of every chunk there is a '@@' followed by a number of line; also
 218 lines starting with plus means add, and minus means delete, if I'm not
 219 clear you should google how to use diff and patch to modify a file.
 220 
 221 ## More screenshots
 222 
 223 #### Debugging [6502 emulator](https://github.com/mjkloeckner/6502) with dwm, vim and tmux
 224 
 225 [![Debugging 6502 emulator](debugging.jpeg)](debugging.png "Debugging 6502 emulator")
 226 &nbsp;
 227 
 228 
 229 #### Floating window manager?
 230 
 231 [![Floating show](floating.jpeg)](floating.png "Floating show while raining")
 232 
 233 ## Useful links
 234 
 235 - [What is a window manager?](https://en.wikipedia.org/wiki/Window_manager)
 236 - Make sure to check the [suckless webiste](https://suckless.org/)
 237 - [suckless dwm website](https://dwm.suckless.org/)
 238 - [X server man page](https://www.x.org/releases/X11R7.7/doc/man/man1/Xserver.1.xhtml)
 239 - [patch man page](https://man7.org/linux/man-pages/man1/patch.1.html)