tonybtw.com

tonybtw.com

https://git.tonybtw.com/tonybtw.com.git git://git.tonybtw.com/tonybtw.com.git
13,586 bytes raw
1
#+TITLE: DWM on Arch | Minimal Config Tutorial
2
#+AUTHOR: Tony, btw
3
#+DATE: 2025-04-27
4
#+HUGO_TITLE: DWM on Arch | Minimal Config Tutorial
5
#+HUGO_FRONT_MATTER_FORMAT: yaml
6
#+HUGO_CUSTOM_FRONT_MATTER: :image "/img/dwm.png" :showTableOfContents true
7
#+HUGO_BASE_DIR: ~/www/tonybtw.com
8
#+HUGO_SECTION: tutorial/dwm
9
#+EXPORT_FILE_NAME: index
10
#+OPTIONS: toc:nil broken-links:mark
11
#+HUGO_AUTO_SET_HEADLINE_SECTION: nil
12
#+DESCRIPTION: A complete DWM setup on Arch Linux with minimal patches, autostart, custom bar, and keybinds.
13
14
* Table of Contents :toc:noexport:
15
- [[#introduction][Introduction]]
16
- [[#installation][Installation]]
17
- [[#modifying-configh-keybinds][Modifying config.h (Keybinds)]]
18
- [[#aliases][Aliases]]
19
- [[#commands][Commands]]
20
- [[#autostart][Autostart]]
21
- [[#patches][Patches]]
22
- [[#dwmblocks][DWMBlocks]]
23
- [[#custom-icons--fonts][Custom Icons & Fonts]]
24
- [[#my-personal-keybinds][My personal keybinds]]
25
- [[#dwm-keybindings][DWM Keybindings]]
26
- [[#final-thoughts][Final Thoughts]]
27
28
* Introduction
29
30
This is a full DWM tutorial for Arch users who want a minimal, fast, patched build without bloat.
31
32
The philosophy of the developers of dwm is as follows:
33
Keep things simple, minimal and usable.
34
35
#+begin_quote
36
"Unfortunately, the tendency for complex, error-prone and slow software seems to be prevalent in the present-day software industry. We intend to prove the opposite with our software projects. "
37
– DWM Developers
38
#+end_quote
39
40
Because of this philosophy, DWM is blazingly fast, and strikes a balance of minimalism, efficienty, and extensibility.
41
42
You’ll get a working, beautiful setup with basic patches, autostart, a functional bar, and a clean workflow.
43
44
* Installation
45
46
The pre-requisites for today's tutorial are: xorg, make, gcc, and a few others. If you follow the video guide,
47
I'm starting from almost a brand new arch install, so you can just start from that, and get the following packages like so:
48
49
50
#+begin_src sh
51
pacman -S git base-devel xorg xorg-xinit xorg-xrandr
52
git clone https://git.suckless.org/dwm
53
cd dwm
54
sudo make clean install
55
#+end_src
56
57
We will need st as well, a terminal manager made by the developers of dwm. Same concept here.
58
59
#+begin_src sh
60
git clone https://git.suckless.org/st
61
cd st
62
sudo make clean install
63
#+end_src
64
65
Note: If you are on another distribution such as Debian, or Gentoo, getting dwm will be exactly the same, but getting the xorg server and developer tools to build dwm (base-devel on arch) will be slightly different. Refer
66
to your distribution's handbook on how to get these tools.
67
68
I personally am a 'startx' kinda guy, but if you have a display manager, just add dwm to your display manager list.
69
70
Last thing here is to add exec dwm to the .xinitrc file:
71
72
#+begin_src sh
73
echo 'exec dwm' >> .xinitrc
74
#+end_src
75
76
* Modifying config.h (Keybinds)
77
78
Alright, let's open a terminal here and start modifying config.h.
79
80
#+begin_src sh
81
chown -R dwm
82
cd dwm; vim config.h
83
#+end_src
84
85
The first thing we want to do is head on down to the modkey section, and change
86
mod1mask to mod4mask (this changes the mod key from alt to super)
87
88
#+begin_src c
89
#define MODKEY Mod4Mask
90
#define TAGKEYS(KEY,TAG) \
91
	{ MODKEY,                       KEY,      view,           {.ui = 1 << TAG} }, \
92
	{ MODKEY|ControlMask,           KEY,      toggleview,     {.ui = 1 << TAG} }, \
93
	{ MODKEY|ShiftMask,             KEY,      tag,            {.ui = 1 << TAG} }, \
94
	{ MODKEY|ControlMask|ShiftMask, KEY,      toggletag,      {.ui = 1 << TAG} },
95
#+end_src
96
97
Let's take a look at the keybinds section here, and I'm going to change stuff for my personal needs, you feel free to tinker with this as usual. The usual suspects for me are, change opening a terminal to Super + Enter,
98
change the application launcher menu to Super + D, and change closing a program to Super + Q.
99
100
#+begin_src c
101
static const Key keys[] = {
102
	/* modifier                     key        function        argument */
103
	{ MODKEY,                       XK_r,      spawn,          {.v = dmenucmd } },
104
	{ MODKEY,                       XK_Return, spawn,          {.v = termcmd } },
105
	{ MODKEY,                       XK_b,      togglebar,      {0} },
106
	{ MODKEY,                       XK_q,      killclient,     {0} },
107
	TAGKEYS(                        XK_1,                      0)
108
	TAGKEYS(                        XK_2,                      1)
109
};
110
#+end_src
111
112
Once you're done with these first small changes, go ahead and run:
113
114
#+begin_src sh
115
sudo make clean install; pkill x; startx
116
#+end_src
117
118
Beautiful. You've succesfully rebuilt your first DWM binary. You can officialy tell all of your friends that you are a C developer. Let's move on to the next step.
119
120
* Aliases
121
122
For QoL, I like to use 2 aliases for dwm, one to just jump into the config file, and another to rebuild dwm.
123
So if you want those, open up your bashrc file and add these aliases:
124
125
#+begin_src bash
126
alias cdwm="vim ~/dwm/config.h"
127
alias mdwm="cd ~/dwm; sudo make clean install; cd -";
128
#+end_src
129
130
This will make it so you can jump straight into your config.h file, and rebuild dwm from anywhere and return back to whatever directory you were in after rebuilding it.
131
132
* Commands
133
134
Let's mess with some of the commands. I like to use rofi, although dmenu is perfectly fine if not better, rofi just ports over really nice to all my other configs, so I'll show you how to set that up in dwm.
135
136
First, ensure rofi is installed, and a config.rasi exists in .config/rofi/config.rasi (feel free to copy my config.rasi file [[https://www.github.com/tonybanters/rofi][here]])
137
138
Let's jump back into config.h, and look at the commands section.
139
140
#+begin_src c
141
static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */
142
static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL };
143
static const char *termcmd[]  = { "st", NULL };
144
static const char *firefoxcmd[]  = { "firefox-bin", NULL };
145
static const char *slock[]    = { "slock", NULL };
146
static const char *screenshotcmd[] = { "/bin/sh", "-c", "maim -s | xclip -selection clipboard -t image/png", NULL };
147
static const char *rofi[]  = { "rofi", "-show", "drun", "-theme", "~/.config/rofi/config.rasi", NULL };
148
static const char *emacsclient[]  = { "emacsclient", "-c", "-a", "", NULL };
149
#+end_src
150
151
These are some of my commands. Notice I have rofi, slock which is a minimal screen lock tool, a screenshot command which just utilizes main and xclip, and i've got an emacsclient command. Don't worry about that emacs command if you are below the age of 30.
152
153
Make sure to add these commands to the keybind section like so:
154
155
#+begin_src c
156
static const Key keys[] = {
157
	/* modifier                     key        function        argument */
158
	{ MODKEY,                       XK_r,      spawn,          {.v = dmenucmd } },
159
	{ MODKEY,                       XK_e,      spawn,          {.v = emacsclient } },
160
	{ MODKEY,                       XK_Return, spawn,          {.v = termcmd } },
161
	{ MODKEY,                       XK_l,      spawn,          {.v = slock } },
162
	{ ControlMask,                  XK_Print,  spawn,          {.v = screenshotcmd } },
163
	{ MODKEY,                       XK_d,      spawn,          {.v = rofi } },
164
	{ MODKEY,                       XK_b,      spawn,          {.v = firefoxcmd } },
165
    ...
166
};
167
#+end_src
168
169
* Autostart
170
171
Use this to launch programs like wallpaper setter, bar, compositor: (if they are not in .xinitrc)
172
173
#+begin_src c
174
/* add this to config.h */
175
static const char *autostart[] = {
176
  "dwm-autostart.sh", NULL
177
};
178
#+end_src
179
180
Example script:
181
182
#+begin_src sh
183
#!/bin/sh
184
xwallpaper --zoom ~/wall.png &
185
dwmblocks &
186
picom -b
187
#+end_src
188
189
* Patches
190
191
Alright, patches are something that deters people from using dwm because they feel it can be daunting, but its really easy.
192
193
Head on over to: [[https://dwm.suckless.org/patches][DWM's Official Community Patch List]]
194
195
Grab a patch, vanity-gaps for example, and right click the patch, and save link as. Put this in dwm/patches/
196
197
To patch your dwm, just run
198
199
#+begin_src sh
200
patch -i ~/dwm/patches/name-of-patch.diff
201
#+end_src
202
203
Hopefully you don't get any errors, but if you do, they are usually pretty simple to resolve. Checkout my video on dwm to learn more about resolving patches.
204
205
After that, remake dwm with the `mdwm` alias, and restart x. Boom, your patch is ready to go.
206
207
* DWMBlocks
208
209
DWM Blocks is a program that renders blocks in the top right of the dwm bar. Similar to widgets in Qtile, or polybar modules. These blocks can all be customizable sh scripts, and ricing this will be for another tutorial, but for now the base version is good enough. You can take mine as well:
210
211
Install:
212
#+begin_src sh
213
git clone https://github.com/tonybanters/dwmblocks
214
cd dwmblocks
215
sudo make clean install
216
#+end_src
217
218
Basic usage:
219
Add `dwmblocks &` to your autostart script.
220
221
* Custom Icons & Fonts
222
For a custom font, I like jetbrains mono nerd font, and we can just install it like so:
223
224
#+begin_src sh
225
sudo pacman -S ttf-jetbrains-mono-nerd
226
#+end_src
227
228
And we can set that font in `config.h`:
229
230
#+begin_src c
231
static const char *fonts[] = { "JetBrainsMono Nerd Font:size=14" };
232
#+end_src
233
234
* My personal keybinds
235
236
If you want to just clone my build of dwm, thats perfectly fine, just take a look at this table here for my keybinds as a guide:
237
238
* DWM Keybindings
239
240
| Modifier            | Key         | Action            | Description                         |
241
|---------------------+-------------+-------------------+-------------------------------------|
242
| MOD                 | r           | spawn             | Launch dmenu                        |
243
| MOD                 | Return      | spawn             | Launch terminal                     |
244
| MOD                 | l           | spawn             | Lock screen (slock)                 |
245
| Ctrl                | Print       | spawn             | Screenshot                          |
246
| MOD                 | d           | spawn             | Launch Rofi                         |
247
| MOD                 | b           | togglebar         | Toggle top bar                      |
248
| MOD                 | j           | focusstack +1     | Focus next window                   |
249
| MOD                 | k           | focusstack -1     | Focus previous window               |
250
| MOD                 | i           | incnmaster +1     | Increase master windows             |
251
| MOD                 | p           | incnmaster -1     | Decrease master windows             |
252
| MOD                 | g           | setmfact -0.05    | Shrink master area                  |
253
| MOD                 | h           | setmfact +0.05    | Grow master area                    |
254
| MOD                 | z           | incrgaps +3       | Increase gaps                       |
255
| MOD                 | x           | incrgaps -3       | Decrease gaps                       |
256
| MOD                 | a           | togglegaps        | Toggle gaps                         |
257
| MOD+Shift           | a           | defaultgaps       | Reset gaps                          |
258
| MOD                 | Tab         | view              | Toggle last workspace               |
259
| MOD                 | q           | killclient        | Close focused window                |
260
| MOD                 | t           | setlayout tile    | Set tiling layout                   |
261
| MOD                 | f           | setlayout float   | Set floating layout                 |
262
| MOD                 | m           | setlayout monocle | Set monocle layout                  |
263
| MOD                 | c           | setlayout custom1 | Custom layout (slot 3)              |
264
| MOD                 | o           | setlayout custom2 | Custom layout (slot 4)              |
265
| MOD+Shift           | Return      | setlayout default | Reset to default layout             |
266
| MOD+Shift           | f           | fullscreen        | Toggle fullscreen                   |
267
| MOD+Shift           | Space       | togglefloating    | Toggle floating                     |
268
| MOD                 | 0           | view all tags     | View all workspaces                 |
269
| MOD+Shift           | 0           | tag all           | Move window to all tags             |
270
| MOD                 | ,           | focusmon -1       | Focus monitor left                  |
271
| MOD                 | .           | focusmon +1       | Focus monitor right                 |
272
| MOD+Shift           | ,           | tagmon -1         | Send window to monitor left         |
273
| MOD+Shift           | .           | tagmon +1         | Send window to monitor right        |
274
| MOD                 | 1–9         | view tag N        | Switch to tag N                     |
275
| MOD+Shift           | 1–9         | tag window to N   | Move window to tag N                |
276
| MOD+Shift           | q           | quit              | Exit DWM                            |
277
| (none)              | XF86Audio+  | pactl +3%         | Raise volume                        |
278
| (none)              | XF86Audio-  | pactl -3%         | Lower volume                        |
279
280
#+caption: Default keybindings in my DWM setup
281
282
* Final Thoughts
283
284
This setup is minimalist but powerful. From here, you can add more patches (like systray or gaps), or just keep it lean.
285
286
Thanks so much for checking out this tutorial. If you got value from it, and you want to find more tutorials like this, check out
287
my youtube channel here: [[https://youtube.com/@tony-btw][YouTube]], or my website here: [[https://www.tonybtw.com][tony,btw]]
288
289
You can support me here: [[https://ko-fi.com/tonybtw][kofi]]