“dwm is an extremely fast, small, and dynamic window manager for X.” - suckless.org

This post talks about my dwm configuration and the changes I have made to it. I have installed quite a few patches and made some modifications of my own, I have also added a flake.nix to make installation on NixOS really simple. You can view the source code in my GitHub repository here.

Patches

Below is a list of all the patches I have installed with a short explanation of each patch, click the links to view the patches on suckless.org.

  • alwayscenter: “All floating windows are centered, like the center patch, but without a rule.”

  • attachbottom: “New clients attach at the bottom of the stack instead of the top.”

  • center first window: Adds rule to center window if it is the only client in a tag.

  • cfacts: Provides the ability to assign weights to clients to modify how the space in the stacks is distributed between the clients.

  • cursorwarp: “Warp the cursor to the center of the target window when switching between them with focusstack(), focusmon(), manage() and unmanage()”

  • exitmenu: “Simple exit menu for dwm.”

  • hide vacant tags: “This patch prevents dwm from drawing tags with no clients (i.e. vacant) on the bar.”

  • movestack: “This plugin allows you to move clients around in the stack and swap them with the master. It emulates the behavior off mod+shift+j and mod+shift+k in Xmonad.”

  • resizecorners: “By default, windows can only be resized from the bottom right corner. With this Patch, the mouse is warped to the nearest corner and you resize it from there.”

  • restartsig: Allows restarting of dwm.

  • scratchpad: “The scratchpad patch allows you to spawn or restore a floating terminal window. It is usually useful to have one to do some short typing.”

  • splitstatus: “This patch replaces the standard statusbar items (window name to the right of the tags, and status on the right) with two status items: one in the centre, and one on the right.”

  • swallow: Terminals swallow windows opened by child processes.

  • tilewide: “The tilewide layout is a variant of the standard tile layout. Windows added to the master area will be positioned side by side, instead of one on top of the other. This makes better use of screen space on ultra wide monitors.”

  • viewontag: “Follow a window to the tag it is being moved to.”

Other Changes

Some other modifications that I have made to my dwm fork is that I have changed the font to FiraCode Nerd Font and I have changed the colors to colors inspired by the Nord theme. On top of this I have also modified the keybindings, see the keybinds section below, including adding XF86XK keys for controlling volume, brightness, and media playback.

Keybinds

Applications

  • Super + d: Spawn dmenu
  • Super + s: Spawn st
  • Super + p: Spawn scratchpad
  • Super + b: Spawn Bitwarden-menu
  • Super + w: Spawn qutebrowser

Clients and Areas

  • Super + j: Focus next client
  • Super + k: Focus previous client
  • Super + i: Increase number of master clients
  • Super + u: Decrease number of master clients
  • Super + h: Decrease master area size
  • Super + l: Increase master area size
  • Super + Shift + h: Increase client weight
  • Super + Shift + l: Decrease client weight
  • Super + Shift + o: Reset client weight
  • Super + Shift + j: Swap client with next client
  • Super + Shift + k: Swap client with previous client
  • Super + Shift + Space: Toggle client to floating
  • Super + Return: Zoom client to master area
  • Super + q: Kill client

Layout

  • Super + t: Set tilewide layout
  • Super + Shift + t: Set tile layout
  • Super + f: Set floating layout
  • Super + m: Set monocle layout
  • Super + Space: Toggle previous layout
  • Super + Shift + b: Toggle the bar

Tags and Monitors

  • Super + Tab: View previous tag

  • Super + 0: View all tags

  • Super + Shift + 0: Move client to all tags

  • Super + ,: Focus previous monitor

  • Super + .: Focus next monitor

  • Super + Shift ,: Move client to previous monitor

  • Super + Shift .: Move client to next monitor

  • Super + 1-9: View tag 1-9

  • Super + Shift + 1-9: Send client to tag 1-9

  • Super + Control + 1-9: Add tag 1-9 to view

  • Super + Shift + Control + 1-9: Add client to tag 1-9

Other

  • Super + Shift + q: Open exit menu

Install

Dependencies

  • libX11
  • libXinerama
  • libXft
  • fira-code-nerdfont

Note: On NixOS dependencies are automatically installed.

NixOS

Add this repo as a flake input in your flake.nix:

inputs = {
    dwm = {
        url = "github:jonwin1/dwm-jonwin";
        inputs.nixpkgs.follows = "nixpkgs";
    };
};

Then add the following to your configuration.nix to enable dwm:

services = {
    xserver = {
        windowManager.dwm = {
            enable = true;
            package = inputs.dwm.packages."x86_64-linux".default;
        };
    };
};

Rebuild your NixOS and after a reboot dwm should be available as a window manager.

Configurations updates can easily be installed by updating the flake lock and rebuilding. Run the following to only update the dwm flake input:

nix flake lock --update-input dwm

Running dwm

Dwm should automatically be started when you login to your computer or have been added as an option in your login manager.

Other Distros

The following is taken from the dwm README and should work on most Linux distributions.


Edit config.mk to match your local setup (dwm is installed into the /usr/local namespace by default).

Afterwards enter the following command to build and install dwm (if necessary as root):

make clean install

Running dwm

Add the following line to your .xinitrc to start dwm using startx:

exec dwm

In order to connect dwm to a specific display, make sure that the DISPLAY environment variable is set correctly, e.g.:

DISPLAY=foo.bar:1 exec dwm

(This will start dwm on display :1 of the host foo.bar.)

In order to display status info in the bar, you can do something like this in your .xinitrc:

while xsetroot -name "`date` `uptime | sed 's/.*,//'`"
do
	sleep 1
done &
exec dwm

Note: I would recommend using a tool like slstatus to set your status bar instead of xsetroot like suggested above, you can find my slstatus config here.