Files
quickshell_bar/README.md
T
2026-07-26 13:48:27 +02:00

132 lines
4.8 KiB
Markdown

# quickshell-bar
A Wayland status bar for [Sway](https://swaywm.org/), i3,
[Hyprland](https://hypr.land/) and attwm (a dwm-like window manager for
[river](https://codeberg.org/river/river)), built with
[Quickshell](https://quickshell.outfoxxed.me/) and packaged with Nix flakes.
![bar](docs/bar.png)
## Modules
Left → right:
| Module | Source |
|-------------|------------------------------------------|
| Workspaces | Sway/i3 IPC (`Quickshell.I3`), Hyprland IPC, or attwm tags |
| Layout | attwm only — layout symbol, click to cycle |
| 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
- A supported window manager, detected from the environment at startup:
Sway/i3 (`$SWAYSOCK`/`$I3SOCK`), Hyprland
(`$HYPRLAND_INSTANCE_SIGNATURE`), or attwm — assumed when neither of the
other two announces itself, and talking to
`$XDG_RUNTIME_DIR/attwm-$WAYLAND_DISPLAY.sock` (override with
`$ATTWM_SOCKET`).
- 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
```sh
# 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:
```sh
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.
## Use it from attwm
attwm is started by river, so launch the bar from river's init alongside it:
```sh
#!/bin/sh
# ~/.config/river/init
quickshell-bar &
exec attwm
```
Tags replace workspaces: all nine are always shown, dim when empty, underlined
when they hold windows you aren't looking at. Left click views a tag, right
click toggles it into the view, middle click sends the focused window there.
The layout symbol sits to their right — click to cycle forward, right click
back. A bar can only map at all because attwm binds `river_layer_shell_v1`.
## 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** — `interval` in `services/SysStats.qml` (kept in sync with
the argument passed to `stats.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)
Compositor.qml which window manager are we under? env only (singleton)
services/
SysStats.qml reads /proc & /sys via FileView into reactive props (singleton)
Attwm.qml attwm IPC socket: state in, commands out (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
WorkspaceChip.qml one workspace/tag chip, shared by every backend
Workspaces.qml LayoutSymbol.qml Clock.qml CpuGraph.qml CpuTemp.qml
Ram.qml Disk.qml Network.qml Volume.qml Tray.qml Battery.qml
```