A minimal, dwm-inspired tiling window manager written in Rust using x11rb.
- Master-stack tiling — first window gets left half, rest stack on the right
- Resizable master —
Super+h/lshrinks/grows the master area (like dwm's mfact) - Focus follows mouse — EnterNotify driven, no click-to-focus
- Focus cycling —
Super+j/kcycles focus without rearranging windows - Window swapping —
Super+Shift+j/kswaps window positions in the layout - Kill focused window — graceful
WM_DELETE_WINDOW, falls back toXKillClient - Gaps — configurable pixel gaps between windows and screen edges
- 9 workspaces — switch with
Super+1..9, move windows withSuper+Shift+1..9, or click the bar - Clickable status bar — workspace indicators + focused window title
- Fullscreen toggle —
Super+f, covers entire screen including bar - Wallpaper — auto-set via
xwallpaperon startup (configurable path) - Compositor — picom launched on startup for transparency
- App launchers — dmenu, browser, file manager, htop, ncmpcpp, etc.
- Media keys — volume, brightness, mpc playback, mute, screenshots
- Last workspace —
Super+Tabtoggles between current and previous workspace - Crash-resistant — X11 errors are handled gracefully, no panics on dead windows
| Binding | Action |
|---|---|
Super + Return |
Spawn terminal (alacritty) |
Super + d |
dmenu_run |
Super + q |
Kill focused window |
Super + Shift + q |
Quit rwm |
Super + j |
Focus next window |
Super + k |
Focus previous window |
Super + Shift + j |
Swap focused window with next |
Super + Shift + k |
Swap focused window with previous |
Super + h |
Shrink master area |
Super + l |
Grow master area |
Super + f |
Toggle fullscreen |
Super + Tab |
Switch to last workspace |
Super + Backspace |
sysact |
Super + 1..9 |
Switch to workspace 1–9 |
Super + Shift + 1..9 |
Move focused window to workspace 1–9 |
| Click bar number | Switch to that workspace |
| Binding | Action |
|---|---|
Super + w |
librewolf |
Super + Shift + w |
nmtui (network manager) |
Super + r |
lfub (file manager) |
Super + Shift + r |
htop |
Super + n |
nvim VimwikiIndex |
Super + m |
ncmpcpp |
Super + p |
mpc toggle |
Super + Shift + p |
mpc pause + pauseallmpv |
| Binding | Action |
|---|---|
Super + - |
Volume -5% |
Super + Shift + - |
Volume -15% |
Super + = |
Volume +5% |
Super + Shift + = |
Volume +15% |
Super + Shift + m |
Mute toggle |
XF86 AudioMute |
Mute toggle |
XF86 AudioLower/Raise |
Volume ±3% |
XF86 AudioPlay/Prev/Next/Stop |
mpc controls |
XF86 BrightnessUp/Down |
xbacklight ±15 |
XF86 AudioMicMute |
Mic mute toggle |
| Binding | Action |
|---|---|
Print |
Full screenshot (maim) |
Shift + Print |
maimpick (selection) |
cargo build --releaseXephyr :1 -screen 1280x720 &
DISPLAY=:1 ./target/release/rwmInstall the session file:
sudo cp rwm.desktop /usr/share/xsessions/rwm.desktopThen select rwm from LightDM's session dropdown at login.
Add to ~/.xinitrc:
exec /path/to/rwmThen startx from a TTY.
Edit constants in src/config.rs:
pub const TERMINAL: &str = "alacritty";
pub const LAUNCHER: &str = "dmenu_run";
pub const BROWSER: &str = "librewolf";
pub const WALLPAPER: &str = "/path/to/wallpaper.png";
pub const GAP: u32 = 8;
pub const BAR_HEIGHT: u16 = 20;
pub const NUM_WORKSPACES: usize = 9;
pub const BAR_BG: u32 = 0x222222;
pub const BAR_FG: u32 = 0xbbbbbb;
pub const BAR_SEL_BG: u32 = 0x005577;The master area defaults to 55% width and can be adjusted at runtime with Super+h/Super+l.
src/
├── main.rs entry point, event loop, keybinding dispatch, startup (wallpaper, picom)
├── config.rs all user-tunable constants (like dwm's config.h)
├── keys.rs keysym constants, XF86 media keys, keycode translation
├── client.rs per-window state: geometry, fullscreen, workspace
├── layout.rs pure-geometry tiling math with adjustable mfact (no X11 calls)
├── bar.rs status bar: clickable workspace indicators + window title
└── wm.rs core WM: manage, focus, kill, workspaces, fullscreen, mfact, window swapping
- Rust 2024 edition
x11rb0.13 — pure Rust X11 bindings (no C deps)xwallpaper— wallpaper (runtime)picom— compositor (runtime)maim— screenshots (runtime)
I maybe switching dmenu to a dynamic user-defined menu written by me.
This project is licensed under the GNU General Public License v3.0 — see LICENSE for details.
