Howto: dwm configuration and installation
- Loomx
- Posts: 55
- Joined: 2010年09月28日 01:11
Howto: dwm configuration and installation
Post by Loomx »
This howto is aimed at anyone from low-intermediate level upwards. You will need to be familiar with the terminal, root vs normal user commands and the basic Debian file-system structure (but the less you know now, the more you learn as you go, right? :) )
This howto also assumes that you are familiar with using a window manager, such as openbox, as opposed to a Desktop Environment like Gnome, KDE or XFCE.
Substitute 'apt-get' for 'aptitude' if you prefer.
Any commands with a # at the start means "as root".
Overview:
Part 1: Preparation
Part 2: Configuration
Part 3: Installation
* Note: This howto will discuss two ways of installing dwm: the generic, quick-and-dirty "make install" way, and the ‘proper’ APT/Debian way. Both ways have their ups and downs; as always, it’s your system, just be aware of your choices.
***************************************************************
Part 1: Preparation
Before we start, let’s get the dependencies: (they are probably already on your system if you’re using X anyway)
Code: Select all
# aptitude install libc6 libx11-6 libxinerama1Code: Select all
# aptitude build-dep dwm
# aptitude install make gccCode: Select all
# aptitude install suckless-toolsCode: Select all
# aptitude install xfonts-terminusSo, make a directory to put the dwm source into, for example:
Code: Select all
mkdir ~/BuildCode: Select all
cd ~/Build
apt-get source dwm
cd dwm_6.0 # (or whatever it is)But what we really want to do is customise this baby, so...
*****************************************************************
Part 2: Configuration
Copy the default config file to config.h then open it.
Use whatever editor you prefer to modify config.h, but I would recommend using one that allows syntax highlighting to help you understand what you’re doing :)
Code: Select all
cp config.def.h config.h
vim config.hCode: Select all
/* See LICENSE file for copyright and license details. */
/* appearance */
static const char font[] = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*";
static const char normbordercolor[] = "#cccccc";
static const char normbgcolor[] = "#cccccc";
static const char normfgcolor[] = "#000000";
static const char selbordercolor[] = "#0066ff";
static const char selbgcolor[] = "#0066ff";
static const char selfgcolor[] = "#ffffff";
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */
static const Bool showbar = True; /* False means no bar */
static const Bool topbar = True; /* False means bottom bar */The selected window has a one-pixel border by default, of color #0066ff (red, I think)
The background and foreground colors refer to the status bar.
Code: Select all
/* tagging */
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
static const Rule rules[] = {
/* class instance title tags mask isfloating monitor */
{ "Gimp", NULL, NULL, 0, True, -1 },
{ "Firefox", NULL, NULL, 1 << 8, False, -1 },
};The rules define how certain windows get treated, e.g. Gimp is always floating (not tiled or monocle/fullscreen) as it doesn't work properly otherwise.
The "tags mask" defines which tag the window appears on. Basically read the "<<" as "+", so "1 << 8" means Firefox will be on tag 9.
0 means any tag.
Code: Select all
/* layout(s) */
static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
static const Bool resizehints = True; /* True means respect size hints in tiled resizals */
static const Layout layouts[] = {
/* symbol arrange function */
{ "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
};Above that you can select the amount of the screen that the master window takes up.
Code: Select all
/* key definitions */
#define MODKEY Mod1Mask
#define TAGKEYS(KEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },The TAGKEYS set what happens if you press the number for a tag along with a modifier, so Alt-3 will take you to tag 3, while Alt-Shift-3 will tag (attach) a window to tag 3.
Code: Select all
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }Now we get to the guts of it, the commands:
Code: Select all
/* commands */
static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
static const char *termcmd[] = { "uxterm", NULL };
static Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawn, {.v = dmenucmd } },
{ MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
{ MODKEY, XK_b, togglebar, {0} },
{ MODKEY, XK_j, focusstack, {.i = +1 } },
{ MODKEY, XK_k, focusstack, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} },
{ MODKEY, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} },
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
{ MODKEY, XK_comma, focusmon, {.i = -1 } },
{ MODKEY, XK_period, focusmon, {.i = +1 } },
{ MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
{ MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
TAGKEYS( XK_1, 0)
TAGKEYS( XK_2, 1)
TAGKEYS( XK_3, 2)
TAGKEYS( XK_4, 3)
TAGKEYS( XK_5, 4)
TAGKEYS( XK_6, 5)
TAGKEYS( XK_7, 6)
TAGKEYS( XK_8, 7)
TAGKEYS( XK_9, 8)
{ MODKEY|ShiftMask, XK_q, quit, {0} },
};XK_p means the button ’p’, etc.
If instead of ‘MODKEY’ you put ‘0’, that would mean ‘no modifier’.
‘focusstack’ means next or previous window, depending on the +1 or -1
‘setmfact’ means set the size of the master window in tiling mode
‘zoom’ is move a window to the master window in tiling mode
‘setlayout’ chooses a layout based on the order defined earlier, starting numbering from 0
The TAGKEYS select the tags - note that the tags as far as dwm is concerned number from 0-8.
Lastly, Alt-Shift-q quits dwm and takes you back to a tty.
Code: Select all
/* button definitions */
/* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, 0, Button3, toggleview, {0} },
{ ClkTagBar, MODKEY, Button1, tag, {0} },
{ ClkTagBar, MODKEY, Button3, toggletag, {0} },
};‘ClkLtSymbol’ means ‘click layout symbol’.
**********************************************************
As you can see, there are a lot of options. The default config basically chucks them all in so you can use what you need and ditch what you don’t.
I have found that I don’t need most of the options, so here is my config.h for reference after I took to it with a knife and added a couple of tricks:
Code: Select all
/* See LICENSE file for copyright and license details. */
/* appearance */
static const char font[] = "7x14";
static const char normbordercolor[] = "#000000";
static const char normbgcolor[] = "#cccccc";
static const char normfgcolor[] = "#000000";
static const char selbordercolor[] = "#cccccc";
static const char selbgcolor[] = "#0066ff";
static const char selfgcolor[] = "#ffffff";
static const unsigned int borderpx = 1; /* border pixel of windows */
static const unsigned int snap = 32; /* snap pixel */
static const Bool showbar = True; /* False means no bar */
static const Bool topbar = True; /* False means bottom bar */Code: Select all
/* tagging */
static const char *tags[] = { "Here", "There" };
static const Rule rules[] = {
/* class instance title tags mask isfloating monitor */
{ NULL, NULL, NULL, 0, False, -1 },
};Code: Select all
/* layout(s) */
static const float mfact = 0.5; /* factor of master area size [0.05..0.95] */
static const Bool resizehints = False; /* True means respect size hints in tiled resizals */
static const Layout layouts[] = {
/* symbol arrange function */
{ "[ ]", monocle }, /* first entry is default */
{ "[]=", tile },
};‘resizehints = false’ so terminal windows don’t leave odd gaps around the edges.
Code: Select all
/* key definitions */
#define MODKEY Mod1Mask
#define TAGKEYS(KEY,TAG) \
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
{ MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
{ MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
#include <X11/XF86keysym.h>
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }Code: Select all
/* commands */
static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
static const char *termcmd[] = { "xterm", "-rv", "-fn", font, NULL };
static const char *chromiumcmd[] = { "chromium-browser", "--proxy-server=172.31.232.250:3128", NULL };
static const char *play[] = { "mocp", "-G", NULL };
static const char *stop[] = { "mocp", "-x", NULL };
static const char *prev[] = { "mocp", "-r", NULL };
static const char *next[] = { "mocp", "-f", NULL };
static const char *mute[] = { "amixer", "-q", "set", "Master", "toggle", NULL };
static const char *volumedown[] = { "amixer", "-q", "set", "Master", "2%-", "unmute", NULL };
static const char *volumeup[] = { "amixer", "-q", "set", "Master", "2%+", "unmute", NULL };
static const char *eject[] = { "eject", NULL };Also you need to define what command each of your XF86 keys will execute.
Code: Select all
static Key keys[] = {
/* modifier key function argument */
{ 0, XF86XK_Launch1, spawn, {.v = dmenucmd } },
{ 0, XK_F6, spawn, {.v = termcmd } },
{ 0, XK_F7, spawn, {.v = chromiumcmd } },
{ 0, XF86XK_AudioPlay, spawn, {.v = play}},
{ 0, XF86XK_AudioStop, spawn, {.v = stop}},
{ 0, XF86XK_AudioPrev, spawn, {.v = prev}},
{ 0, XF86XK_AudioNext, spawn, {.v = next}},
{ 0, XF86XK_AudioMute, spawn, {.v = mute}},
{ 0, XF86XK_AudioLowerVolume, spawn, {.v = volumedown}},
{ 0, XF86XK_AudioRaiseVolume, spawn, {.v = volumeup}},
{ 0, XF86XK_Eject, spawn, {.v = eject}},
{ MODKEY, XK_Tab, focusstack, {.i = +1 } },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY, XK_z, zoom, {0} },
{ MODKEY, XK_q, killclient, {0} },
{ MODKEY|ControlMask, XK_q, quit, {0} },
TAGKEYS( XK_comma, 0)
TAGKEYS( XK_period, 1)
};The XF86 key "Launch1" for dmenu is actually the Super/Windows key, which I remap in ~/.xinitrc (see near the end of this howto)
Alt-space simply toggles between monocle and tiling modes, as they are the only modes I specified earlier.
Alt-comma and alt-period are for "Here" and "There" tags.
Code: Select all
static Button buttons[] = {
/* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkWinTitle, 0, Button1, spawn, {.v = dmenucmd } },
{ ClkWinTitle, 0, Button3, spawn, {.v = termcmd } },
{ ClkTagBar, 0, Button1, view, {0} },
{ ClkTagBar, ControlMask, Button1, toggleview, {0} },
{ ClkTagBar, 0, Button3, tag, {0} },
{ ClkTagBar, ControlMask, Button3, toggletag, {0} },
};Click on a tag name to view it; right-click on a tag name to send a window to that tag.
So that’s mine; go to town, or just try the default first, whatever. When you're done there, it’s time for...
*******************************************************************
Part 3: Installation
a) The generic quick-and-dirty method
This is the method from the README file. It will put dwm into /usr/local/bin which is good for two reasons: that directory is empty by default in Debian, and it is already in your $PATH
The disadvantage of this method is that APT will not be aware of its existence, so you have been warned.
The advantage is that it is, well, quick:
Code: Select all
# make clean installb) The ‘proper’ APT/Debian way
Once you have it set up how you want, you can make a .deb and install it properly.
This is straightforward too; just run this to make the .deb (from in the ~/Build/dwm_6.0 directory):
Code: Select all
dpkg-buildpackage -us -ucWhen it finishes you should find your .deb in the parent directory, so cd up one level and install like so (as root):
Code: Select all
cd ..
# dpkg -i dwm*.debDon’t forget to uninstall the file at /usr/local/bin/dwm (if you used the quick-and-dirty method) like this:
Code: Select all
cd ~/Build/dwm_6.0
# make uninstallCode: Select all
# aptitude hold dwm**************************
You need to make (or alter) the executable file ~/.xinitrc to start dwm
The last line in it should be
Code: Select all
exec [...] dwmCode: Select all
#!/bin/sh
. ~/.fehbg # set wallpaper
unclutter -root & # hide cursor when unused
# Turn Super/Windows key into XF86Launch1
xmodmap -e "keycode 133 = XF86Launch1"
# Turn CapsLock into Control
xmodmap -e "clear lock" -e "keycode 66 = Control_R" -e "add Control = Control_R"
# Show memory use, volume %, battery % and time in status bar
while xsetroot -name "$(free -m | awk '/cache:/ { print 3ドル"MB" }') Vol:$(amixer get Master | tail -1 | awk '{ print 5ドル }' | tr -d '[]') Batt:$(acpi | awk '{ print 4ドル }' | tr -d ',') $(date +%R)"
do
sleep 1
done &
# Launch system-wide stuff first, then dwm...
exec ck-launch-session dbus-launch dwmCode: Select all
chmod 755 ~/.xinitrcCode: Select all
startx**************************
Some sources:
http://dwm.suckless.org/tutorial
http://dwm.suckless.org/customisation/
http://www.xsnake.net/howto/dwm/dwm-eng.php
http://wiki.archlinux.org/index.php/Dwm
http://lubutu.com/rant/dwm-faq
You can also extend dwm with patches to add features like new layouts, such as b.stack (horizontal stacking, good for non-widescreens); see http://dwm.suckless.org/patches
Have fun!
Any errors in this howto are mine, and if you point them out I can fix them :)
(Edited many times for clarity and freshness)
- Loomx
- Posts: 55
- Joined: 2010年09月28日 01:11
Re: Howto: dwm configuration and installation
Post by Loomx »
(and this relates to dwm how?) :?
- dmhdlr
- Posts: 266
- Joined: 2011年04月17日 23:44
- Location: Philadelphia
Re: Howto: dwm configuration and installation
Post by dmhdlr »
Return to "Docs, HowTos, Tips & Tricks"
- Debian Development
- ↳ Debian Development Discussion
- ↳ Debian News
- Documentation
- ↳ Docs, HowTos, Tips & Tricks
- Help and Support
- ↳ Installation
- ↳ Beginners Questions
- ↳ General Questions
- ↳ Graphical Environments & Desktops
- ↳ System and Network configuration
- ↳ Hardware
- ↳ Programming
- Testing & Unstable
- ↳ Testing And Unstable
- Debian User Projects
- ↳ Debian User Projects - Software
- ↳ Debian User Projects - F/LOSS Contributions
- Community
- ↳ Forum information, requests, and feedback.
- ↳ General Debian
- ↳ Off-Topic
-
- Newest Posts
- Top Active Users
- Newest Users
-
-
-
Reinstalling grub in the removable path by mazda1 France » 2025年12月05日 13:18 » in Hardware
hello,
when I installed trixie on an external ssd drive I forgot to install grub in the removable path. I know how to correct it when this ssd is in... -
[Trixie] AMD GPU 'flip_done timed out' crash by LuxFerre » 2025年12月05日 10:45 » in Testing And Unstable
I have a 9070 AMD radeon GPU, running trixie RC1 with non-free-firmware.
KDE is crashing often, the sound still works, I can change to tty5 and kill... -
Can cube desktop effect be setup in trixie ? by Stuarte Scotland » 2025年12月05日 10:42 » in Graphical Environments & Desktops
Hi,
I'm trying to set up the cube desktop effect in trixie/kde plasma but is seems to be missing. I did a web search and the AI overview reported... -
[HowTo] How I got a 56% Temperature Drop with udev Rule -- ... by distro-nix France » 2025年12月05日 10:04 » in Docs, HowTos, Tips & Tricks
*** UPDATE *** I have confirmed this procedure works on Debian 13 (Trixie) with 6.16.43+deb13-amd64 kernel. The temperature is the same...
-
[Discussion] Any Software-defined radio (SDR) users here? by peer Netherlands » 2025年12月05日 10:02 » in Off-Topic
I'm considering dipping my toes into the land of SDR/Linux and was curious if there were any users here?
-
Reinstalling grub in the removable path by mazda1 France » 2025年12月05日 13:18 » in Hardware
-
-
nmuzi Argentina
Joined: 2025年12月05日 10:11 -
colonelquestions
Joined: 2025年12月05日 07:19 -
moja7tk Vietnam
Joined: 2025年12月05日 06:43 -
[画像:User avatar] Resplendent606 United States of America
Joined: 2025年12月05日 06:41 -
babacom
Joined: 2025年12月05日 06:27
-
nmuzi Argentina
-