Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Installation

A supported Debian-, Arch-, or Fedora/RHEL-family distribution with Xorg is required.

The easiest way is via Linutil:

curl -fsSL https://christitus.com/linux | sh

In the TUI, press v to multi-select, then select dwm, bash prompt, and alacritty. Press Enter to install.

linutil-appinstall

Manual Install

1. Dependencies

The supported dependency path is the installer because it resolves package names for Debian-, Arch-, and Fedora/RHEL-family systems from the shared map:

./install.sh --dry-run --non-interactive --profile core
./install.sh --profile full

Use core for the required build/X11/session packages and one terminal, recommended for the desktop layer, or full for optional extras such as file-manager integration, portals, wallpapers, and display-manager setup.

2. Clone and Build

git clone https://github.com/ChrisTitusTech/dwm-titus.git
cd dwm-titus
cp config.def.h config.h
make
sudo make install

Automated Installer

./install.sh

The script detects the distribution family and handles dependency installation, font copying, display-manager integration, and config placement. Existing user configuration and .xinitrc files are preserved.

Installer package profiles are selected with DWM_INSTALL_PROFILE:

  • core: required build packages, X11/session runtime, and one supported terminal.
  • recommended: core plus the recommended desktop layer such as Quickshell, Quickshell, Picom, Feh, Dex, fonts, theming, screenshot, audio, Bluetooth control and tray tools, and brightness tools. It also installs portable GTK theme packages where available and installs Nordic system-wide for the default Nord theme.
  • full: recommended plus optional extras such as file-manager integration, network tray utilities, portals, wallpapers, and display-manager setup.

The default is full to preserve the historical automated installer behavior. For a minimal install:

DWM_INSTALL_PROFILE=core ./install.sh

The same profile can be selected with a flag:

./install.sh --profile core

Interactive runs print the resolved package plan before prompting. For CI, packaging checks, or scripted validation, use the non-interactive flags:

./install.sh --dry-run --non-interactive --profile core
./install.sh --non-interactive --yes --profile recommended

Starting dwm

Display manager (SDDM, GDM, LightDM): log out and select dwm from the session list.

startx:

startx

The provided .xinitrc disables screen blanking, starts the configured Quickshell panel, and runs dwm.

Minimal Session Profile

The minimal supported profile is useful for lean systems, recovery sessions, and portability testing. It keeps only:

  • an X11 server and either a display-manager session or startx
  • D-Bus session support
  • dwm
  • one supported terminal available through dwm-terminal
  • required X11 helpers used by core startup and display commands, such as xrandr, xset, and xsetroot

Quickshell, Picom, Feh, Dex, a polkit agent, screenshot tools, wallpapers, tray utilities, and audio or brightness helpers are optional in this profile. Missing optional components should appear as degraded features in dwm-diagnostics, not as session-fatal failures.

For startx, a minimal .xinitrc can be:

#!/bin/sh
xset s off
xset -dpms
xsetroot -cursor_name left_ptr
exec dbus-run-session dwm

If the login path already creates a user D-Bus session, use exec dwm instead of wrapping it with dbus-run-session.

After installation, verify the profile with:

dwm-diagnostics
dwm-terminal --print-command

dwm-diagnostics must report zero required failures before treating the minimal profile as ready. Optional degraded features can remain unresolved.

Last change:

Getting Started

After installing, the first thing to know: Super = the Windows key.

Press Super + / at any time to open the interactive keybind viewer.

Essential Actions

ActionKeys
Open terminalSuper + X
App launcher (Quickshell)Super + R
Close windowSuper + Q
Power menuSuper + Ctrl + Q
Control CenterSuper + F1
Keybind viewerSuper + /

Switching Tags (Workspaces)

Tags 1–9 act as workspaces. Use Super + a number to switch.

ActionKeys
Switch to tagSuper + 19
Move window to tagSuper + Shift + 19
Show all tagsSuper + 0

Layouts

Three layouts are available — switch between them instantly.

LayoutKeys
Tiling (master + stack)Super + T
FloatingSuper + Shift + M
Fullscreen (monocle)Super + M

See Keybindings for the full reference.

Last change:

Keybindings

Press Super + / inside dwm to open a live, searchable Quickshell keybind viewer.

MODKEY = Super (Windows key) in the shipped config.h.

Bindings are defined in config/hotkeys.toml and reload instantly on save — no recompile needed.


Launchers

KeysAction
Super + RApp launcher (Quickshell)
Super + XTerminal
Super + EFile manager
Super + BBrowser
Super + /Keybind viewer
Super + F1Control Center

Screenshots

KeysAction
Super + PFull screenshot
Super + Shift + PScreenshot selection → file
Super + Ctrl + PScreenshot selection → clipboard

Web Apps

KeysAction
Super + AChatGPT
Super + Shift + AGemini
Super + Shift + XX/Twitter — new post

Window Management

KeysAction
Super + JFocus next window
Super + KFocus previous window
Super + Shift + JMove window down in stack
Super + Shift + KMove window up in stack
Super + ReturnPromote window to master
Super + QClose window
Super + IAdd window to master area
Super + DRemove window from master area
Super + HShrink master area
Super + LExpand master area
Super + Shift + HIncrease window cfact size
Super + Shift + LDecrease window cfact size
Super + Shift + OReset window cfact

Layouts

KeysAction
Super + TTiling layout
Super + MFullscreen (monocle)
Super + SpaceToggle floating for window
Super + Shift + MToggle floating for window
Super + Shift + YFake fullscreen (bar stays)
Super + Shift + BToggle bar visibility

Tags (Workspaces)

KeysAction
Super + 19Switch to tag
Super + Ctrl + 19Also show tag alongside current
Super + Shift + 19Move window to tag
Super + Ctrl + Shift + 19Also show window on that tag
Super + 0Show all tags
Super + TabPrevious tag

Multi-Monitor

KeysAction
Super + ,Focus left monitor
Super + .Focus right monitor
Super + Shift + ,Send window to left monitor
Super + Shift + .Send window to right monitor

Media Keys

KeysAction
XF86AudioRaiseVolumeVolume up
XF86AudioLowerVolumeVolume down
XF86AudioMuteMute toggle
XF86MonBrightnessUpBrightness up
XF86MonBrightnessDownBrightness down

Session & Power

KeysAction
Super + Ctrl + QPower menu
Super + Shift + QQuit dwm
Super + Ctrl + Shift + RReboot
Super + Ctrl + Shift + SSuspend

Mouse

ActionFunction
Super + Left dragMove window
Super + Middle clickToggle floating
Super + Right dragResize window

Customizing Keybinds

Edit config/hotkeys.toml — changes take effect on save, no recompile required.

[vars]
terminal = "dwm-terminal"

keys = [
  { mod="SUPER SHIFT", key="f", desc="Firefox", func="spawn", exec=["firefox"] },
]

See the comments in hotkeys.toml for a full list of func values and modifier syntax.

The browser binding uses dwm-default-apps open. Configure it with dwm-default-apps browsers and dwm-default-apps set-browser <desktop-id>.

Last change:

Configuration

dwm-titus uses two TOML config files that live-reload on save — no recompile needed for most changes.

FilePurpose
config/hotkeys.tomlAll keybindings
config/themes.tomlColors, themes, border size

For deeper changes (window rules, fonts, refresh rate), edit config.h and run make && sudo make install.


config.h Essentials

config.h is your personal copy of config.def.h. It is created automatically by make if it doesn’t exist.

$EDITOR config.h
make && sudo make install

Key Options

SettingDescription
refresh_rateMatch your monitor (default 60; set 120 for high-refresh)
fonts[]Font family and size used in the bar
colors[]Managed by themes.toml — rarely edit directly
autostart[]Programs launched on dwm start
rules[]Per-app window rules (floating, tag assignment, terminal flag)
keys[]Fallback static keybinds (prefer hotkeys.toml)
MODKEYMod4Mask = Super, Mod1Mask = Alt

Window Rules

Rules in config.h let you assign windows to specific tags or force float:

/* class      instance  title   tags mask  isfloating  isterminal  noswallow  monitor */
{ "Gimp",     NULL,     NULL,   0,         1,          0,           0,        -1 },
{ "Firefox",  NULL,     NULL,   1 << 1,    0,          0,          -1,        -1 },

hotkeys.toml — Live Keybinds

Add or change bindings without recompiling. Save the file and they apply instantly.

[vars]
terminal = "dwm-terminal"
webapp   = "webapp-launch"

keys = [
  { mod="SUPER",       key="x",  desc="Terminal",    func="spawn", exec=["$terminal"] },
  { mod="SUPER SHIFT", key="f",  desc="Firefox",     func="spawn", exec=["firefox"] },
]

dwm-terminal selects the first installed supported terminal at launch time. Set DWM_TERMINAL or replace terminal with a specific command if you want a fixed terminal.

Default applications use freedesktop settings. Run dwm-default-apps browsers to list browser desktop files, dwm-default-apps set-browser firefox.desktop to set the default browser, or dwm-default-apps set-mime <mime> <desktop-id> for other file types.

Display profiles are optional files under ${XDG_CONFIG_HOME:-$HOME/.config}/dwm-titus/display-profiles. Use dwm-display-profile template to print the format, dwm-display-profile list to show profiles, and dwm-display-profile apply <name> to run the profile through xrandr.

Modifier Syntax

Use space-separated modifiers: "SUPER", "SUPER SHIFT", "SUPER CTRL", "SUPER CTRL SHIFT".

Available Functions

funcParametersDescription
spawnexec=[...] or cmd="..."Run a program
killclientClose focused window
zoomPromote/demote master
focusstacki=1 or i=-1Focus next/prev window
movestacki=1 or i=-1Reorder in stack
incnmasteri=1 or i=-1Change master count
setmfactf=0.05 or f=-0.05Resize master area
setcfactf=0.25 / f=-0.25 / f=0.00Resize window slot
setlayoutlayout_idx=0/1/20=tile, 1=float, 2=monocle
togglefloatingFloat/tile window
fullscreenTrue fullscreen
togglefakefullscreenFullscreen with bar
togglebarShow/hide bar
focusmoni=1 or i=-1Focus monitor
tagmoni=1 or i=-1Send window to monitor
viewui=-1 = all tagsSwitch tag
quitExit dwm

Tag Bindings

Tag bindings auto-generate all four variants (switch, toggle-view, move, toggle-tag):

tag_keys = [
  { key="1", tag=0 },
  { key="2", tag=1 },
]

Notes on XDG Autostart

Recommend using Flatpak to install programs on startup:

flatpak install flathub io.github.flattool.Ignition

or you can create your own .desktop file in ~/.config/autostart/

set-refresh.desktop Example:

[Desktop Entry]
Type=Application
Exec=xrandr --output HDMI-0 --primary --mode 1920x1080 --pos 0x0 --rotate normal --rate 120 --output DP-0 --off --output DP-1 --off --output DP-2 --off --output DP-3 --off --output DP-4 --off --output DP-5 --off
Hidden=false
X-GNOME-Autostart-enabled=true
Name=Set Refresh
Last change:

Theming

Themes are defined in config/themes.toml. Change the active theme and save to update dwm, terminal, GTK, and Qt styling. No restart needed.

[active]
theme = "nord"   # ← change this line to switch themes

Available Themes

Dark

ThemeDescription
nordArctic, cool blue palette (default)
draculaPurple-tinted dark theme
gruvboxWarm retro earth tones
catppuccinMocha variant — soft pastels
tokyonightDeep blue-grey night theme
onedarkAtom One Dark inspired
solarizedDark variant of Solarized
rosepineMuted rose/pine tones
everforestMuted green forest palette
monochromeBlack and white minimal

Light

ThemeDescription
catppuccin-latteCatppuccin light variant
gruvbox-lightWarm light tones
solarized-lightClassic Solarized light
rosepine-dawnRose Pine dawn variant
tokyonight-dayTokyo Night day variant

Border Size

[appearance]
borderpx = 1   # 0 = no border, 1 = thin (default), 2-3 = thicker

What Each Theme Controls

Each [theme.name] section sets colors for all components:

KeyApplies To
normfgcolor / normbgcolor / normbordercolorUnfocused bar and windows
selfgcolor / selbgcolor / selbordercolorFocused window and active tag
term_bg / term_fg / term_cursorTerminal background, text, cursor
term_color0term_color15Full 16-color terminal palette
dark_modeGTK dark preference and Capitaine cursor variant (true / false)
gtk_themeOptional installed GTK theme name for GTK apps such as Thunar

Creating a Custom Theme

Add a new section to themes.toml:

[theme.mytheme]
normfgcolor     = "#cdd6f4"
normbgcolor     = "#1e1e2e"
normbordercolor = "#313244"
selfgcolor      = "#cdd6f4"
selbgcolor      = "#89b4fa"
selbordercolor  = "#89b4fa"

term_bg         = "#1e1e2e"
term_fg         = "#cdd6f4"
term_cursor     = "#f5e0dc"
# ... term_color0-15 ...
dark_mode       = true
gtk_theme       = "Nordic"

Then set theme = "mytheme" under [active] and save.


Applying Themes via Control Center

Open the Control Center with Super + F1, navigate to Appearance → Select Theme, and pick from the list. The theme switches immediately.


Wallpapers

Place images in ~/Pictures/backgrounds/. Use Super + Shift + W to randomize, or set a specific one:

feh --bg-fill ~/Pictures/backgrounds/mywall.jpg
Last change:

Control Center

The Control Center is a Quickshell utility window for system health, quick actions, appearance settings, and keybind discovery.

Open: Super + F1, or run dwm-controlcenter from a terminal.

The window floats above normal clients like the launcher, network popover, and power menu. Press Esc to close it.


Network Popover

The panel network indicator opens a Quickshell network popover. It shows active NetworkManager connections, scans visible Wi-Fi networks, and connects to open or WPA personal networks directly. Successful Wi-Fi connections are saved as NetworkManager profiles, so they reconnect normally in later sessions.

Hidden SSIDs and enterprise Wi-Fi are handled through the optional nm-connection-editor fallback when it is installed.


Modules

System Health

Runs a full dependency check and reports:

  • Build tools (cc, make) and required libraries
  • Xorg / Xlibre installation
  • Runtime programs: quickshell, picom, feh, flameshot, bluetoothctl, blueman-applet
  • Terminal emulators (alacritty, kitty, st)
  • Fonts: MesloLGS Nerd, Noto Color Emoji
  • Running services: picom, NetworkManager
  • Config paths: .xinitrc, Quickshell config, wallpaper folder

Selecting a failed item offers to run install.sh (auto-fix) or check-deps.sh (details).

Quick Actions

ActionDescription
Restart PicomKill and relaunch the compositor
Reload WallpaperRandomize from ~/Pictures/backgrounds/
Toggle CompositorStart or stop picom
Restart NetworkManagersudo systemctl restart NetworkManager
Run Dependency CheckOpens check-deps.sh in a terminal
Install Missing DepsRuns install.sh in a terminal

Appearance

ActionDescription
Select ThemePick from all themes defined in themes.toml
Randomize WallpaperRandom image from ~/Pictures/backgrounds/
Open Wallpaper FolderOpen folder in file manager
GTK Theme SettingsLaunch nwg-look for GTK theming

Keybind Viewer

Displays all bindings from hotkeys.toml in a searchable Quickshell list. Same as pressing Super + /.


Running from Terminal

dwm-controlcenter

The script is a compatibility wrapper around the Quickshell IPC target:

quickshell ipc --path "${XDG_DATA_HOME:-$HOME/.local/share}/dwm-titus/config/quickshell/shell.qml" call controlcenter toggle
Last change:

Patches & Features

dwm-titus is a heavily patched build. Below is every addition on top of stock dwm.


Window Management Patches

Pertag

Each tag independently remembers its layout, master count, and master/stack sizing. Switching tags restores the previous layout for that tag.

Cfact

Assign per-window size weights within the stack area. Windows are no longer forced to equal height.

KeysAction
Super + Shift + HGrow this window’s slot
Super + Shift + LShrink this window’s slot
Super + Shift + OReset to equal sizing

Movestack

Reorder windows within the stack without using the mouse.

KeysAction
Super + Shift + JMove window down
Super + Shift + KMove window up

Window Swallowing

When a GUI application is launched from a terminal, it replaces the terminal in the layout. Closing the app brings the terminal back.

Controlled via window rules in config.h:

{ "Alacritty", NULL, NULL, 0, 0, 1, 0, -1 },  /* isterminal = 1 */

Fullscreen (3-State)

Three fullscreen modes available:

ModeKeysDescription
True fullscreenSuper + MHides bar, takes full screen
Fake fullscreenSuper + Shift + YLooks fullscreen, bar still usable
Monocle layoutSingle window view, bar visible

Bar & EWMH

Quickshell Integration

The managed Quickshell layer reads dwm workspace and active-window state through EWMH-compatible helpers so the panel stays synchronized with X11 state.

EWMH Compliance

Implements _NET_WM_STATE, _NET_CURRENT_DESKTOP, _NET_NUMBER_OF_DESKTOPS, and related atoms so external tools and taskbars work correctly.

Window Icons

Title bar icons via _NET_WM_ICON. Applications that set this atom display their icon in the bar.

Systray

A built-in system tray is compiled in and can be configured in config.h.


Visual

Noborder

When only one window is visible on a tag, its border is automatically removed for a cleaner look. Borders return when a second window appears.

Cursor Warp

When focus moves to a different window or monitor (via keyboard), the mouse cursor warps to the center of the newly focused window.


Live Configuration

TOML Hotkeys (hotkeys.toml)

Keybindings are parsed from config/hotkeys.toml at runtime. Edit and save — bindings update without recompiling or restarting dwm.

TOML Themes (themes.toml)

Colors for dwm, terminal, GTK, and Qt are sourced from config/themes.toml. Save the file to apply a new theme instantly across supported apps.


Scripts & Utilities

ScriptDescription
dwm-controlcenterQuickshell control center (Super+F1)
dwm-keybindsSearchable keybind viewer (Super+/)
dwm-screenshotWrapper for flameshot (full, gui, clip modes)
theme-apply.shApplies active theme from themes.toml to all apps
webapp-createCreates a web app shortcut
webapp-launchLaunches a URL as a standalone web app window
autostart.shRuns programs on dwm start
check-deps.shChecks all required dependencies
disable-powersavingDisables DPMS and screen blanking

Multi-Monitor

Xinerama support keeps tags independent per monitor. Windows can be moved between monitors with Super + Shift + ,/..

Last change:

Troubleshooting

Run the dependency checker first — it covers most common issues:

dwm-diagnostics

Or use the Control CenterSystem Health.


dwm Won’t Start

Black screen / returns immediately to login:

  • Run dwm-diagnostics and resolve any required X11/session failures.
  • Preview required packages with ./install.sh --dry-run --profile core.
  • Check .xinitrc exists and ends with exec dwm
  • Run startx from a TTY to see error output in the terminal

dwm: cannot open display:

  • You must launch dwm from a TTY, not an existing X session
  • If using a display manager, ensure dwm.desktop is in /usr/share/xsessions/

No Status Bar / Quickshell Missing

  • Install the recommended desktop layer: ./install.sh --profile recommended
  • Verify the managed config exists: ls ~/.config/quickshell/shell.qml
  • Run manually: quickshell --no-duplicate
  • Check fonts: fc-list | grep -i meslo

Terminal Won’t Open (Super+X)

  • Run dwm-terminal from an existing shell to see the exact fallback message
  • Install a supported terminal: alacritty, kitty, st, warp-terminal, or xterm
  • Or set a fixed terminal in config/hotkeys.toml:
    [vars]
    terminal = "alacritty"
    

Browser Won’t Open (Super+B)

  • Run dwm-default-apps status to inspect the current default browser
  • Run dwm-default-apps browsers to list installed browser desktop files
  • Set one with dwm-default-apps set-browser firefox.desktop
  • Ensure xdg-utils is installed so xdg-settings, xdg-mime, and xdg-open are available

Themes Not Applying

  • Confirm themes.toml is at ~/.config/dwm-titus/themes.toml
  • Check the [active] section has a valid theme name
  • Manually trigger: kill -USR1 $(pidof dwm)
  • Run theme-apply.sh directly to see any errors

Keybinds Not Working

  • Check config/hotkeys.toml for syntax errors — invalid TOML silently fails
  • Verify the key name is correct (use xev to find X11 key names)
  • If a bind still doesn’t work, add it as a fallback in config.h and recompile

Multi-Monitor Issues

  • Tags not syncing across monitors: run dwm-diagnostics
  • Cursor doesn’t follow focus: verify cursor warp is enabled in config.h (cursorwarp = 1)
  • Display layout profiles: run dwm-display-profile dir and dwm-display-profile template to create optional xrandr profiles

NVIDIA / Suspend Issues

  • Black screen on wake: run scripts/nvidia-suspend-test.sh to diagnose
  • DPMS/screensaver issues: run scripts/disable-powersaving or add it to autostart

Picom / Compositor Artifacts

Restart picom via the Control Center (Quick Actions → Restart Picom) or:

pkill picom; setsid -f picom --backend xrender

If artifacts persist, set a different backend in ~/.config/picom.conf or run with PICOM_BACKEND=glx or PICOM_BACKEND=egl.


Still Stuck?

Last change: