- C 88.5%
- Shell 6.3%
- Roff 3.3%
- Makefile 1.9%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
gvfs-backends lets Thunar mount and browse smb:// shares, but without the FUSE bridge at /run/user/<uid>/gvfs, non-GIO apps (mpv, editors, etc.) silently fail to open files on those shares. Reported in butterknife#12. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
| docs | ||
| screenshots | ||
| suckless | ||
| .gitignore | ||
| CHANGELOG.md | ||
| checklist.md | ||
| install.sh | ||
| LICENSE | ||
| QUICKSTART.md | ||
| README.md | ||
🔲 dwm-setup
A minimal suckless DWM 6.8 setup for Debian-based systems.
Following the suckless philosophy with carefully selected patches — simple, efficient, and hackable.
📚 Full documentation lives on the dwm-setup wiki — keybinds, patches, customization, multi-monitor, upgrading, troubleshooting. The README below is a quick reference; the wiki has the deep dive.
📝 Recent changes: see
CHANGELOG.md.
Part of the JustAGuy Linux window manager collection — installable standalone or via butterknife, the installer for Butterbian.
📜 Suckless Philosophy
This setup adheres to the suckless philosophy:
- Simplicity - Minimal code, maximum functionality
- Clarity - Configuration through clean C header files
- Hackability - Easy to understand, modify, and extend
Configuration follows the suckless way: edit config.def.h, remove config.h, then recompile — no bloated config systems.
🚀 Installation
Quick Install
git clone https://justaguy.dev/drew/dwm-setup.git
cd dwm-setup
chmod +x install.sh
./install.sh
⚠️ XLibre users: This script installs
xorgas part of its core packages, which will replace XLibre if you've installed it. RemovexorgfromPACKAGES_COREininstall.shbefore running, or use--only-configto skip package installation entirely.
🪵 Branches:
mainis the active release,devis where ongoing work lands. The previous release is preserved on thelegacybranch as a fallback —git clone -b legacy ...to install it.
Installation Options
The installer follows the suckless principle of simplicity:
./install.sh [OPTIONS]
Options:
--only-config Only copy config files (perfect for non-Debian distros)
--help Show usage information
Distribution-Agnostic Installation
⚠️ UNSUPPORTED: Instructions for other distributions (click to expand)
IMPORTANT: These instructions are provided as-is for advanced users. Non-Debian distributions are NOT officially supported. Package names and availability may vary. Use at your own risk.
Manual Installation Process:
- Install equivalent packages using your distro's package manager
- Run
./install.sh --only-configto copy configuration files - Compile and install suckless tools manually:
cd ~/.config/suckless/dwm && sudo make clean install cd ~/.config/suckless/slstatus && sudo make clean install cd ~/.config/suckless/st && sudo make clean install cd ~/.config/suckless/tabbed && sudo make clean install
Note: Some packages may have different names or may not be available in all distributions. You may need to find equivalents or install from source.
Advanced Usage Examples
# Update only configuration files (no packages)
./install.sh --only-config
# Standard installation with optional tools prompt
./install.sh
Note: The script can be run from any location - it automatically detects its directory.
What Gets Installed
The installer follows the suckless approach - only what's necessary:
- System Update - Updates package lists and upgrades existing packages
- Core Packages - Essential X11, build tools, and suckless dependencies
- UI Components - Window manager utilities (picom, rofi, dunst, etc.)
- System Tools - File manager, audio controls, power management
- Suckless Builds - Compiles and installs dwm (+
dwmtabshelper), slstatus, st, and tabbed - External Tools - Via butterscripts:
- Kitty (terminal emulator)
- Nerd Fonts collection
- Orchis theme & Colloid icons
- LightDM display manager
- Bashrc enhancements
- Optional Tools - Additional browsers, editors, and utilities (prompted)
📦 What It Installs
Suckless Tools & Core Components
| Component | Purpose |
|---|---|
dwm |
Tiling window manager (patched) |
sxhkd |
Keybinding daemon |
slstatus |
Status bar for DWM |
st |
Patched for scratchpad with transparency, scrollback, and clipboard support |
tabbed |
Tab container for X11 applications |
xorg & tools |
Display server and utilities |
build-essential |
Compilation tools |
UI & System Tools
| Component | Purpose |
|---|---|
picom |
Compositor with transparency (via butterrepo) |
rofi |
App launcher + keybind viewer |
dunst |
Lightweight notifications |
feh |
Wallpaper setter |
nwg-look |
GTK theme manager |
network-manager |
Network management applet |
thunar |
File Manager (+plugins) |
pavucontrol |
Audio control GUI |
xfce4-power-manager |
Power management |
flameshot |
Screenshot tool |
qimgv |
Lightweight image viewer |
firefox-esr |
Default web browser |
External Tools (via butterscripts)
| Component | Purpose |
|---|---|
kitty |
Main terminal emulator |
| Nerd Fonts | Icon-enabled fonts |
| Orchis & Colloid | GTK theme and icons |
| LightDM | Display manager |
Optional Tools (prompted during install)
Additional browsers, editors, and utilities available through the optional tools script.
🎨 Appearance & Theming
💡 Special thanks to vinceliuice for the excellent GTK and icon themes.
🔑 Keybindings Overview
Keybindings are split between two systems:
~/.config/suckless/dwm/config.def.hfor DWM-specific keybindings (window management, layout control, tag switching)~/.config/suckless/sxhkd/sxhkdrcfor application launchers and system commands (programs, scripts, media keys)
This separation keeps DWM's core window management bindings in the source while allowing hot-reloadable keybinds for launching applications via sxhkd.
Launch the keybind cheatsheet anytime with:
~/.config/suckless/scripts/help
| Shortcut | Action |
|---|---|
Super + Return |
Launch terminal (kitty) |
Super + Space |
Launch rofi (drun) |
Super + p |
Launch dmenu |
Super + / |
Open keybind cheatsheet (rofi) |
Super + b |
Firefox |
Super + f |
Thunar |
Super + e |
Geany |
Super + x |
Power menu (rofi) |
Super + q |
Close focused window |
Super + j / k |
Focus next / previous window |
Super + Shift + j / k |
Move window down / up in stack |
Super + h / l |
Resize: master width or column cfact |
Super + Shift + Space |
Toggle floating |
Super + Shift + f |
Fullscreen toggle (monocle + hide bar) |
Super + y |
Toggle sticky (show on all tags) |
Super + n |
Toggle window-follow on tag/mon move |
Super + Ctrl + b |
Toggle bar |
Super + apostrophe |
Window switcher (rofi, all tags) |
Super + Shift + l |
Layout menu (rofi) |
Shift + Ctrl + 1..= |
Pick layout directly (12 layouts) |
Super + Tab |
Toggle to previous tag |
Super + 1..9, 0, -, = |
View tag 1..12 |
Super + Shift + 1..= |
Send focused window to tag |
Super + Ctrl + 1..= |
Toggle tag visibility |
Super + , / . |
Focus previous / next monitor |
Super + Shift + , / . |
Send window to prev / next monitor |
Super + ` |
Toggle scratchpad (kitty) |
Super + v |
Toggle pulsemixer scratchpad |
Super + Alt + 1..9 |
Toggle named scratch slot 1..9 |
Super + Alt + Shift + 1..9 |
Promote focused window into slot |
Super + w |
Attach focused window to tab group |
Super + Shift + w |
Detach focused window from tab group |
Super + Shift + t |
Theme switcher (rofi) |
Super + F10 / F11 / F12 |
Mute / volume down / volume up |
Super + Shift + s / s |
Flameshot region / fullscreen |
Super + Escape |
Reload sxhkd |
Super + Shift + r |
Restart dwm (preserves tags/windows) |
Super + Shift + q |
Quit dwm |
⚠️ Editing DWM keybinds: DWM's keybinds live in
dwm/config.hand are compiled in — changing them requires a rebuild (make && sudo make install). The rebuild also regeneratesdwm/keybindings.txt(the Super + / help) from the trailing comments in the keys[] table — edit the comment next to the binding, never the txt, and the help can't drift.
On first login, a welcome notification points to ~/QUICKSTART-dwm.md — a short cheat sheet you can delete when you're comfortable.
Note: sxhkd only reliably binds keys in the
a-z/ standard ASCII range. If you use a non-US keyboard layout (German, French, Russian, Japanese, etc.), bindings that involve characters outside that range may not fire. You'll need to rework the relevantsxhkdrcentries to use keysyms that exist on your layout, or remove them.
🗂️ Tab Management (dwmtabs)
This setup ships with dwmtabs, a small libX11 + Xinerama tool that
reparents windows into a tabbed container — group any X11 application
the way a browser groups pages. Built from suckless/dwm/dwmtabs.c as
part of make; installed alongside the dwm binary.
Usage
Super + w— attach the focused window to a tab group- On the same monitor; auto-creates a
dwm-tabbedcontainer if none exists - Subsequent attaches add to the same container
- On the same monitor; auto-creates a
Super + Shift + w— detach the focused window (or focused tab) back to a standalone window- The container destroys itself when empty
Navigation Within Tabs
Once windows are tabbed together, tabbed's own bindings drive navigation (tabbed's modkey is Alt, set in tabbed/config.def.h to avoid colliding with dwm's Super):
Alt + Tab/Alt + Shift + Tab— next / previous tabAlt + Ctrl + Tab— last (most-recent) tabAlt + 1…0— jump to tab NAlt + Shift + j/k— move current tab left / rightAlt + q— close current tabF11— fullscreen the container
Practical Uses
- Group multiple terminal windows together
- Keep related browser windows organized
- Manage file manager instances in one container
- Reduce window clutter on busy workspaces
🧱 Layouts
Select layouts using Super + Shift + l (rofi menu) or pick directly with Shift + Ctrl + 1..=. 12 layouts ship in the keybind table: Dwindle (default), Tile, Columns (cfact-weighted, i3-style), Centered Master, Floating, Bstack, N-Row Grid, Deck, Gapless Grid, Spiral, Monocle, Grid. Three more — bstackhoriz, centered-floating-master, horizgrid — are compiled in without a default bind; reach them via the layout menu or wire your own key in config.def.h. See the wiki Layouts page for descriptions.
🎭 Theme System
12 themes ship under suckless/dwm/themes/ — catppuccin, doomone, dracula, everforest, github_dark (default), gruvbox, kanagawa, monokai, moonfly, nord, retro, rose_pine. Each theme is a directory of:
dwm.xresources— 6 dwm color keys + st base/ANSI palettetheme.conf— wallpaper, kitty / GTK / icon theme names, dunst colorscolors.rasi— @imported by the rofi configs
Super + Shift + t opens dwm-thememenu (rofi). Picking a theme:
- Merges
dwm.xresourcesinto~/.Xresources(between markers, so old keys don't accumulate) - Swaps wallpaper, dunstrc, rofi configs, kitty color scheme, GTK theme/icons
pkill -HUP dwmtriggersrestartsig— dwm re-execs withpreserveonrestartkeeping tags/windows
Drop a new theme by creating themes/<name>/ with at least dwm.xresources and theme.conf.
📂 Configuration Files
~/.config/suckless/
├── dwm/
│ ├── config.def.h # Main DWM configuration (edit this)
│ ├── dwmtabs # Tab-management binary (built by make)
│ ├── themes/ # Per-theme dwm.xresources + theme.conf
│ └── .current-theme # Tracks the active theme name
├── st/
│ └── config.def.h # ST terminal configuration (scratchpad terminal)
├── slstatus/
│ └── config.def.h # Status bar configuration
├── tabbed/
│ └── config.def.h # Tabbed container configuration
├── sxhkd/
│ └── sxhkdrc # Launchers + tab/theme/system keys
├── dunst/
│ └── dunstrc # Notification settings (overwritten by theme switch)
├── picom/
│ └── picom.conf # Compositor configuration
├── rofi/
│ ├── config.rasi # Main launcher / drun theme
│ ├── window.rasi # Window switcher (super+apostrophe)
│ ├── keybinds.rasi # Help-overlay theme
│ ├── power.rasi # Power menu theme
│ └── colors.rasi # Active palette (@imported by the four .rasi above; replaced on theme switch)
└── scripts/
├── autostart.sh # Startup script
├── help # Keybind viewer (reads keybindings.txt + sxhkdrc)
├── dwm-layout-menu.sh # Rofi layout picker
├── dwm-thememenu # Theme switcher
├── changevolume # Volume up/down/mute with notification
└── power # Power-menu actions
~/.config/kitty/
├── kitty.conf # Terminal configuration
└── current-theme.conf # Written by the theme switcher
🔍 HiDPI / 4K Displays
Tiny type on a 4K screen? There's no single scaling knob — each toolkit (X fonts, GTK, Qt, the cursor) has to be told separately. ~/.config/suckless/scripts/autostart.sh ships a commented HiDPI block near the top; uncomment it and log out / back in. Full walkthrough — 200% vs 150%, GTK/Qt/cursor, the bar font — on the Troubleshooting wiki page under HiDPI / 4K displays.
🧩 Patches Summary
Per-patch descriptions, hand-merge notes, and the "custom modifications beyond patches" list live in
suckless/dwm/modifications.txtand on the wiki Patches page.
21 patches applied. See suckless/dwm/patches/ for the .diff files.
| Patch | Category | Version |
|---|---|---|
| alwayscenter | Floating windows | 2020-06-25 |
| attachbottom | Window order | 6.3 |
| cool_autostart | Autostart | 6.5 |
| ewmhtags | EWMH / pager support | 6.2 |
| fakefullscreen | Window management | 2021-07-14 |
| focusadjacenttag | Navigation | 6.3 |
| focusonnetactive | Compatibility | 6.2 |
| fullscreen | Window management | 2026-01-12 |
| movestack | Window management | 2021-11-15 |
| namedscratchpads | Scratchpads | 6.5 |
| pertag | Layout memory | 2020-09-14 |
| preserveonrestart | Session persistence | 6.3 |
| restartsig | Restart via SIGHUP | 6.2 |
| scratchtagwins | Tabbed scratch slots | 6.5 |
| status2d-barpadding-systray | Bar features + padding | 2024-10-14 |
| statusallmons | Bar features | 6.5 |
| sticky | Window management | 6.5 |
| togglefloatingcenter | Floating windows | 2021-08-06 |
| vanitygaps | Visual spacing | 6.2 |
| windowfollow | Navigation | 2022-10-02 |
| xresources | Theming | 2021-08-27 |
st ships with two additional patches for live theme reload:
st-xresources + st-xresources-signal-reloading (see
suckless/st/patches/).
License
GPL-2.0 - See LICENSE for details.
Support
Connect
- YouTube — tutorials and guides
- Butterforge — source code and projects
- The Butter Lab — Discourse forum
- The Churn — community chat (Fluxer)
- Wiki — documentation and guides
- Mastodon — @justaguylinux@fosstodon.org
- Butterbian — a Debian-based distro
Made with butter by JustAGuyLinux

