3.5 KiB
quickshell-bar
A Wayland status bar for Sway, built with Quickshell and packaged with Nix flakes.
Modules
Left → right:
| Module | Source |
|---|---|
| Workspaces | Sway/i3 IPC (Quickshell.I3) |
| Clock | local time (center) |
| CPU | /proc/stat (per-core load bars + overall %) |
| CPU temp | coretemp/k10temp hwmon, else thermal |
| RAM | /proc/meminfo |
| Disk | df / (every 30s) |
| Network | /sys/class/net/<active>/statistics ↓↑ |
| Volume | PipeWire default sink (scroll/click) |
| Tray | StatusNotifier (Quickshell.Services.SystemTray) |
| Battery | first non-peripheral power_supply |
System metrics are read straight from /proc and /sys in QML via
FileView, polled once a second (services/SysStats.qml) — no persistent
helper process and no per-tick awk/df/cat spawns. Two exceptions have
no virtual-file equivalent: hardware discovery runs once at startup
(services/discover.sh, locating the hwmon temp sensor and main battery),
and disk usage uses df refreshed every 30s (the kernel exposes free space
only via the statvfs syscall). Workspaces, volume, tray and battery icon
use native Quickshell services.
Requirements
- Sway (or i3) — the workspace module talks to
$SWAYSOCK/$I3SOCK. - A running PipeWire session for the volume module.
- Nix with flakes enabled (
experimental-features = nix-command flakes).
Fonts (JetBrains Mono Nerd Font + Inter) are bundled into the package via
FONTCONFIG_FILE, so glyphs render even if they aren't installed system-wide.
Run
# run directly from the flake
nix run .
# or build a wrapper and run it
nix build .
./result/bin/quickshell-bar
During development you can also run it without building:
nix develop # drops you into a shell with quickshell on PATH
quickshell --path . # or: qs -p .
Use it from Sway
Add to ~/.config/sway/config:
# hide the built-in swaybar
bar { mode invisible }
# launch the Quickshell bar (adjust the path to this repo)
exec nix run /path/to/quickshell_bar
Or, if you install the package (e.g. into your system/Home-Manager profile),
just exec quickshell-bar. The bar anchors to the top edge and reserves an
exclusive zone, so windows tile beneath it automatically.
Configuration
Everything is plain QML — edit and the bar hot-reloads.
- Colours, sizes, fonts —
config/Theme.qml(Catppuccin Mocha by default). - Icons —
config/Icons.qml(Nerd Font codepoints). - Poll interval —
intervalinservices/SysStats.qml(kept in sync with the argument passed tostats.sh). - Module order / layout —
widgets/Bar.qml.
Layout
shell.qml entry point — one Bar per monitor
config/
Theme.qml colours, sizes, fonts (singleton)
Icons.qml Nerd Font glyphs (singleton)
services/
SysStats.qml reads /proc & /sys via FileView into reactive props (singleton)
discover.sh one-shot hwmon/battery path discovery at startup
widgets/
Bar.qml the PanelWindow + layout
Pill.qml rounded container used by every module
MetricPill.qml icon + value helper
Workspaces.qml Clock.qml CpuGraph.qml CpuTemp.qml
Ram.qml Disk.qml Network.qml Volume.qml Tray.qml Battery.qml
