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

Arch Linux (or an Arch-based distro) 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, rofi, bash prompt, and ghostty. Press Enter to install.

linutil-appinstall

Manual Install

1. Dependencies

Build:

sudo pacman -S --needed base-devel libx11 libxft libxinerama imlib2 libxcb xcb-util freetype2 fontconfig

Xorg:

sudo pacman -S --needed xorg-server xorg-xinit xorg-xrandr xorg-xsetroot xorg-xset

Runtime:

sudo pacman -S --needed rofi picom dunst feh flameshot dex mate-polkit alsa-utils noto-fonts-emoji ttf-meslo-nerd

Terminal (pick one — ghostty is the default):

sudo pacman -S ghostty   # or: alacritty, kitty

Status bar:

sudo pacman -S polybar

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

3. Fonts

Polybar icon fonts are bundled in config/polybar/fonts/:

mkdir -p ~/.local/share/fonts
cp -r config/polybar/fonts/* ~/.local/share/fonts/
fc-cache -fv

Automated Installer

./install.sh

The script handles all dependency installation, font copying, and config placement.

Starting dwm

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

startx:

startx

The provided .xinitrc disables screen blanking, launches Polybar, and runs dwm.

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 (rofi)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 keybind viewer via rofi.

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 (rofi)
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 = "ghostty"

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.

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 = "ghostty"
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"] },
]

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 — dwm, terminal, rofi, and polybar all update instantly. 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
ghostty_themeGhostty built-in theme name
rofi_themeRofi .rasi theme (filename without extension)
polybar_bg / polybar_fg / polybar_accent / polybar_urgentPolybar colors
dark_modeGTK dark preference (true / false)

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 ...

ghostty_theme   = "Catppuccin Mocha"
rofi_theme      = "sidetab-catppuccin"
polybar_bg      = "#1e1e2e"
polybar_fg      = "#cdd6f4"
polybar_bg_alt  = "#313244"
polybar_fg_alt  = "#a6adc8"
polybar_accent  = "#89b4fa"
polybar_urgent  = "#f38ba8"
dark_mode       = true

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.


Rofi Themes

Rofi theme files live in config/rofi/themes/. The active theme’s rofi_theme key selects which .rasi file is used.

Available rofi themes: nord, onedark, catppuccin, dracula, gruvbox, everforest, monochrome, rosepine, solarized, tokyonight.

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 rofi-based menu providing system health, quick actions, appearance settings, and more.

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

Navigate with arrow keys or type to filter. Press Esc or to go back.


Modules

System Health

Runs a full dependency check and reports:

  • Build tools (cc, make) and required libraries
  • Xorg / Xlibre installation
  • Runtime programs: rofi, picom, dunst, feh, flameshot, polybar
  • Terminal emulators (ghostty, alacritty, kitty, st)
  • Fonts: MesloLGS Nerd, Noto Color Emoji
  • Running services: picom, dunst, polybar, NetworkManager
  • Config paths: .xinitrc, polybar dir, rofi dir, 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
Restart DunstKill and relaunch the notification daemon
Restart PolybarRelaunch using ~/.config/polybar/launch.sh
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
Edit Polybar ConfigOpen polybar config in $EDITOR
GTK Theme SettingsLaunch nwg-look for GTK theming

Keybind Viewer

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


Running from Terminal

dwm-controlcenter

The script auto-detects your terminal emulator (ghostty → alacritty → kitty → st → xterm) and uses the active rofi theme from ~/.config/rofi/themes/controlcenter.rasi.

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:

{ "ghostty", 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

Polybar Integration

The built-in dwm bar is replaced by Polybar. dwm-titus feeds tag and window data to Polybar via EWMH atoms, keeping it fully informed.

Multi-monitor support: each monitor gets its own Polybar instance. The primary monitor hosts the system tray and EWMH tag reporting.

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. It is disabled by default when Polybar is running (to avoid duplication), but can be re-enabled 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, rofi, and polybar are all sourced from config/themes.toml. Save the file to apply a new theme instantly across all apps.


Scripts & Utilities

ScriptDescription
dwm-controlcenterRofi-based 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
active-audioDisplays active audio device in Polybar
disable-powersavingDisables DPMS and screen blanking

Multi-Monitor

Xinerama support with per-monitor Polybar bars. Tags are 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:

bash scripts/check-deps.sh

Or use the Control CenterSystem Health.


dwm Won’t Start

Black screen / returns immediately to login:

  • Verify Xorg: pacman -Q xorg-server xorg-xinit
  • 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 / Polybar Missing

  • Install polybar: sudo pacman -S polybar
  • Verify launch script: ls ~/.config/polybar/launch.sh
  • Run manually: ~/.config/polybar/launch.sh
  • Check fonts: fc-list | grep -i meslo

Missing icons in Polybar:

cp -r config/polybar/fonts/* ~/.local/share/fonts/
fc-cache -fv

Terminal Won’t Open (Super+X)

  • Install a terminal: sudo pacman -S ghostty
  • Or change the terminal in config/hotkeys.toml:
    [vars]
    terminal = "alacritty"
    

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 debug/debug_ewmh.sh
  • Polybar only on one monitor: check ~/.config/polybar/launch.sh uses xrandr to detect monitors
  • Cursor doesn’t follow focus: verify cursor warp is enabled in config.h (cursorwarp = 1)

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; picom -b

If artifacts persist, try disabling experimental backends in ~/.config/picom.conf.


Still Stuck?

Last change: