dwm
dwm is a dynamic window manager for Xorg. It manages windows in tiled, stacked, and full-screen layouts, as well as many others with the help of optional patches. Layouts can be applied dynamically, optimizing the environment for the application in use and the task being performed. dwm is extremely lightweight and fast, written in C and with a stated design goal of remaining under 2000 source lines of code. It provides multihead support for xrandr and Xinerama.
Installation
The prescribed way to install dwm is to clone the official git repo, run make
, and then make install
. dwm can also be installed with the AUR packages dwmAUR or dwm-gitAUR. Make any required #Configuration changes before building and installing, see makepkg.
Configuration
dwm is configured at compile-time by editing some of its source files, specifically config.h
. For detailed information on these settings see the included, well-commented config.def.h
as well as the customisation section on the dwm website.
The official website has a number of patches that can add extra functionality to dwm. These patches primarily make changes to the dwm.c
file but also make changes to the config.h
file where appropriate. For information on applying patches, see the Patching packages article.
Starting
Select Dwm from the menu in a display manager of choice. Alternatively, to start dwm with startx append exec dwm
to ~/.xinitrc
and prepend other programs to execute them as well, for example:
redshift -O3500; xset r rate 300 50; exec dwm
Usage
See the dwm tutorial for information on basic dwm usage.
Tips and tricks
Statusbar configuration
For more examples of status bars see [1].
dwm reads the name of the root window and redirects it to the statusbar. The root window is the window within which all other windows are drawn and arranged by the window manager. Like any other window, the root window has a title/name, but it is usually undefined because the root window always runs in the background.
The information that you want dwm to show in the statusbar should be defined with xsetroot -name ""
command in ~/.xinitrc
or ~/.xprofile
(if you are using a display manager). For example:
xsetroot -name "Thanks for all the fish!"
Dynamically updated information should be put in a loop which is forked to background - see the example below:
# Statusbar loop while true; do xsetroot -name "$( date +"%F %R" )" sleep 1m # Update time every minute done & # Autostart section pcmanfm & exec dwm
In this case the date is shown in ISO 8601 format and PCManFM is launched at startup.
Conky statusbar
Conky can be printed to the statusbar with xsetroot -name
:
(conky | while read LINE; do xsetroot -name "$LINE"; done) & exec dwm
If you do not want to spawn too many PIDs by 'xsetroot' command, you can compile this C program:
#include <string.h> #include <stdlib.h> #include <stdio.h> #include <X11/Xlib.h> int main(int argc, char * argv[]) { Display * dpy = NULL; Window win = 0; size_t length = 0; ssize_t bytes_read = 0; char * input = NULL; dpy = XOpenDisplay(getenv("DISPLAY")); if (dpy == NULL) { fprintf(stderr, "Can't open display, exiting.\n"); exit(1); } win = DefaultRootWindow(dpy); while ((bytes_read = getline(&input, &length, stdin)) != EOF) { input[strlen(input) - 1] = '\0'; XStoreName(dpy, win, input); XFlush(dpy); fprintf(stderr, "Input: %s", input); fprintf(stderr, "\nbytes read: %ld\n", bytes_read); } free(input); return 0; }
Save this code to file dwm-setstatus.c, compile:
$ gcc dwm-setstatus.c -lX11 -o dwm-setstatus
move 'dwm-setstatus' within your $PATH (/usr/local/bin, for example)
# mv dwm-setstatus /usr/local/bin
and run:
$ conky | dwm-setstatus
To do this, conky needs to be told to output text to the console only. The following is a sample conkyrc for a dual core CPU, displaying several usage statistics:
conky.config = { out_to_console = true, out_to_x = false, background = false, update_interval = 2, total_run_times = 0, use_spacer = 'none', }; conky.text = [[ $mpd_smart :: ${cpu cpu1}% / ${cpu cpu2}% ${loadavg 1} ${loadavg 2 3} :: ${acpitemp}c :: $memperc% ($mem) :: ${downspeed eth0}K/s ${upspeed eth0}K/s :: ${time %a %b %d %I:%M%P} ]];
For icons and color options, see dzen.
Restart dwm
To restart dwm without logging out or closing applications, change or add a startup script so that it loads dwm in a while loop, for example:
while true; do # Log stderror to a file dwm 2> ~/.dwm.log # No error logging #dwm >/dev/null 2>&1 done
dwm can now be restarted without destroying other X windows by pressing the usual Mod-Shift-Q combination.
It is a good idea to place the above startup script into a separate file, ~/bin/startdwm
for instance, and execute it through ~/.xinitrc
. Consider running the script with exec
to avoid security implications with remaining logged in after the X server is terminated; see Xinit#Autostart X at login for more information. From this point on, when you wish to end the X session, simply execute killall xinit
, or bind it to a convenient keybind. Alternatively, you could setup your dwm session script so that it relaunches dwm only if the binary changes. This could be useful in the case where you change a setting or update the dwm code base.
# relaunch DWM if the binary changes, otherwise bail csum="" new_csum=$(sha1sum $(which dwm)) while true do if [ "$csum" != "$new_csum" ] then csum=$new_csum dwm else exit 0 fi new_csum=$(sha1sum $(which dwm)) sleep 0.5 done
Bind the right Alt key to Mod4
When using Mod4 (the Super/Windows Key) as the MODKEY
, it may be equally convenient to have the right Alt
key (Alt_R
) act as Mod4
. This will allow you to perform otherwise awkward keystrokes one-handed, such as zooming with Alt_R
+Enter
.
First, find out which keycode is assigned to Alt_R
:
xmodmap -pke | grep Alt_R
Then simply add the following to the startup script (e.g. ~/.xinitrc
), changing the keycode 113 if necessary to the result gathered by the previous xmodmap
command:
xmodmap -e "keycode 113 = Super_L" # reassign Alt_R to Super_L xmodmap -e "remove mod1 = Super_L" # make sure X keeps it out of the mod1 group
After doing so, any functions that are triggered by the Super_L
key press will also be triggered by an Alt_R
key press.
#define
option in config.h which also allows you to switch the modkey.Use both Alt keys as Meta in DWM
- Use xmodmap to assign Alt_L as a secondary meta key in DWM (provided already using Mod1Mask (Alt_R))
~/.xinitrc
/usr/bin/xmodmap -e "clear mod5" /usr/bin/xmodmap -e "keycode 108 = Alt_L"
Space around font in dwm's bar
By default, dwm's bar adds 2px around the size of the font. To change this, modify the following line in dwm.c
:
bh = dc.h = dc.font.height + 2;
Disable focus follows mouse
To disable focus follows mouse behaviour comment out the following line in definiton of struct handler in dwm.c
[EnterNotify] = enternotify,
Note that this change can cause some difficulties; the first click on an inactive window will only bring the focus to it. To interact with window contents (buttons, fields etc) you need to click again. Also, if you have several monitors, you may notice that the keyboard focus does not switch to another monitor activated by clicking.
Floating layout for some windows
For some windows, such as preferences dialogs, it does not make sense for these windows to be tiled - they should be free-floating instead. For example, to make Firefox's preferences dialog float, add the following to your rules array in config.h
:
{ "Firefox", NULL, "Firefox Preferences", 1 << 8, True, -1 },
Using Tilda with dwm
dwm manages placement of windows automatically, so it takes some configuration to make Tilda work properly.
You have to edit dwm's config.h
and recompile/reinstall dwm to properly account for Tilda.
Get the latest PKGBUILD for dwm:
# asp export community/dwm
Copy newest sources to your working directory, I am using ~/sources
:
$ cp -r /var/abs/community/dwm ~/sources
Get into working directory to start config:
$ cd ~/sources/dwm
Edit config.h:
static const Rule rules[] = { /* class instance title tags mask isfloating monitor */ { "Gimp", NULL, NULL, 0, True, -1 }, { "firefox", NULL, NULL, 1 << 8, False, -1 }, //add the line below { "Tilda", NULL, NULL, 0, True, -1 }, { "Volumeicon", NULL, NULL, 0, True, -1 }, };
The above makes all windows with the WM_CLASS "Tilda" floating. The word "Tilda" has to be uppercase (firefox needs lowercase), as shown by
$ xprop |grep WM_CLASS
Save config.h
, then compile and install dwm:
$ makepkg -g >> PKGBUILD && makepkg -efi
Start dwm or restart dwm if it is already active, either by MOD+SHIFT+Q or killing dwm and restarting it.
Launch tilda with -C option:
$ tilda -C
Now you can configure Tilda, the following options are provided as a recommendation:
Font: Clean 9 Appearance: Height: 50%, Width: 70%, Centered Horizontally Extras: Enable Transparency Level 15 Animated Pulldown: 1500 usec, Orientation: Top Colors: Built-in Scheme "Green on Black" Scrolling: Scrollbar is on the left, 2000 lines scrollback Key Binding: F9
Here is what the configuration looks like after those settings in ~/.config/tilda/config_0
:
tilda_config_version = "0.9.6" # image = "" # command = "" font = "Clean 9" key = "F9" title = "Tilda" background_color = "white" # working_dir = "" web_browser = "firefox" lines = 2000 max_width = 956 max_height = 384 min_width = 1 min_height = 1 transparency = 15 x_pos = 205 y_pos = 1 tab_pos = 0 backspace_key = 0 delete_key = 1 d_set_title = 3 command_exit = 2 scheme = 1 slide_sleep_usec = 1500 animation_orientation = 0 scrollbar_pos = 0 back_red = 0 back_green = 0 back_blue = 0 text_red = 0 text_green = 65535 text_blue = 0 scroll_background = true scroll_on_output = false notebook_border = false antialias = true scrollbar = false use_image = false grab_focus = true above = true notaskbar = true bold = true blinks = true scroll_on_key = true bell = false run_command = false pinned = true animation = true hidden = true centered_horizontally = true centered_vertically = false enable_transparency = true double_buffer = false
It is important you enable the pulldown-animation, otherwise Tilda will keep jumping down each time you unhide it, must be a dwm issue.
Troubleshooting
Fixing misbehaving Java applications
Try setting export _JAVA_AWT_WM_NONREPARENTING=1
. Also see the Java page.
Fixing gaps around terminal windows
If there are empty gaps of desktop space outside terminal windows, it is likely due to the terminal's font size. Either adjust the size until finding the ideal scale that closes the gap, or toggle resizehints
to 0 in config.h
.
This will cause dwm to ignore resize requests from all client windows, not just terminals. The downside to this workaround is that some terminals may suffer redraw anomalies, such as ghost lines and premature line wraps, among others.
Alternatively, if you use the st terminal emulator, you can apply the anysize patch and recompile st.
Known issues
Crashes due to Emojis in some fonts
Emojis in title bars may cause dwm to crash with an error similar to the following:
dwm: fatal error: request code=140, error code=16 X Error of failed request: BadLength (poly request too large or internal Xlib length error) Major opcode of failed request: 140 (RENDER) Minor opcode of failed request: 20 (RenderAddGlyphs) Serial number of failed request: 4319 Current serial number in output stream: 4331
This only occurs with some fonts, such as noto-fonts-emoji and bdf-unifont. See [2], [3], [4], [5], and the upstream bug report [6]. Possible workarounds are using a different font or the patch in [7].
An upstream fix has been proposed [8], but as of writing has not been merged. See libxft-bgraAUR and lib32-libxft-bgraAUR for patched versions of libXft, properly displaying emoji without crashing.
See also
- dwm's official website
- Introduction to dwm video
- dmenu - Simple application launcher from the developers of dwm
- The dwm thread on the forums
- Hacking dwm thread
- Wallpaper thread in the forums for a selection of dwm wallpapers
- Show off your dwm configuration forum thread