diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-11 17:02:27 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-11 17:02:27 +0200 |
| commit | 43c31deaa313a8e471ecc3b5a55411a3b93b6f08 (patch) | |
| tree | 77b8b3ae2ac9a69e2b2d749e03e64a8ace0d8668 | |
| parent | d0d878dec69f6e6f99562601b1d6db1c152f724c (diff) | |
| download | quickshell-43c31deaa313a8e471ecc3b5a55411a3b93b6f08.tar.gz quickshell-43c31deaa313a8e471ecc3b5a55411a3b93b6f08.zip | |
docs: add AGENTS.md and a thin CLAUDE.md
Records what cost time rather than what the code already says: the
no-visible-window exit that broke both components, the two measurement
traps that made it look like a code bug, and the per-component findings
that generalise to a third one.
CLAUDE.md points at it, matching unified-desktop-theme, so there is one
source of truth per repo rather than one per agent tool.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G7NRsGyF9jGfPYS4zPqpN7
| -rw-r--r-- | AGENTS.md | 118 | ||||
| -rw-r--r-- | CLAUDE.md | 7 |
2 files changed, 125 insertions, 0 deletions
diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e7e7f65 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,118 @@ +# AGENTS.md + +Guidance for agents working in this repository. + +## What this is + +Quickshell components for a Hyprland desktop, one per directory, each a +complete shell in its own right. They are not modules of a single bar: any of +them runs alone, and running one does not require the others. + + volume-osd/ volume for output and input, plus what is playing + vm-manager/ libvirt drawer: state, live stats, snapshots + +Both are started from `~/.config/hypr/sections/autostart.lua` and keep running +for the whole session. + +## The rule that bites first + +**A quickshell config with no visible window exits.** Both components here are +hidden most of the time, so each holds itself open with a 1x1 transparent +`PanelWindow` with `mask: Region {}`, which is click-through and draws nothing. + +Without it the shell loads, logs `Configuration Loaded`, reports no error, and +quits. The symptom is never an error message: it is a keybind that appears to +do nothing, or a panel that never paints. This was removed once during +development because a process check was measuring the wrong thing, and both +components broke in exactly that way. Any new component needs the same window. + +## Verifying, and how not to + +Two traps cost real time in this repo, both about measurement rather than code. + +**A detached `qs` does not survive an agent's tool call.** Starting one with +`&`, `nohup` or `setsid -f` and then checking `pgrep` in a later call reports +`DEAD` regardless of whether the config is sound. That reads exactly like the +no-visible-window exit above and sent a debugging session in the wrong +direction for a dozen calls. Start it so the harness owns the process, and +confirm with the log rather than a later `pgrep`. + +**`pkill -f` matches the agent's own shell.** The working directory is in the +command line, so `pkill -f quickshell` or `pkill -f "foo.qml"` kills the caller +and returns 144. Use `pkill -x quickshell`. + +For anything visual, ask. Screenshots of a transient OSD are a race, and the +user has the screen. + +## Per-component notes + +Each directory's README carries its own, and they are worth reading before +changing that component. The ones that generalise: + +- **PipeWire nodes report their initial volume before `ready` goes true.** The + `ready` check alone suppresses the startup values. An extra guard on top of + it ate the user's first keypress instead. +- **`PwObjectTracker` is not optional.** Node properties only stay current + while something binds the node; without it the volume reads once and goes + stale. +- **playerctld publishes a duplicate of every MPRIS player** under its own bus + name. Filter by `dbusName`, not by identity. +- **Key events reach a focused item, not a window.** Setting + `WlrLayershell.keyboardFocus` is necessary but not sufficient: + `Keys.onEscapePressed` on a `PanelWindow` never fires. +- **A `Row` sizes to its children, not its parent.** Fixed child widths inside + one overflowed the panel and pushed a button past its edge. +- **libvirt's own memory and disk figures are not what they look like.** + `balloon.current` is memory allocated to the VM and reads full forever; + `block.allocation` is qcow2 growth on the host, not usage inside the guest. + The real numbers come from qemu-guest-agent, and the panel shows a dash + rather than substituting the host-side ones. + +## Theme + +No component defines a palette. `udt-accent`, in the +`unified-desktop-theme` repo alongside this one, writes +`~/.cache/wal/udt-palette.qml` from its `palette.rasi`, carrying the whole +Catppuccin Macchiato palette plus the accent snapped from the current +wallpaper. Each `Theme.qml` parses and watches that file, so a palette edit +recolours a running shell with no restart. + +What is left in `Theme.qml` is a fallback for before the file is read, and for +a machine without unified-desktop-theme. Do not grow it into a second palette: +that duplication is what generating the file removed. + +The file is parsed rather than imported because a generated QML singleton +cannot be imported without a `qmldir` beside it, and the wal cache has no +reason to carry one. + +## Blur + +Translucency is set in QML; the frosting is the compositor's. Hyprland blurs a +layer surface only when a rule names it, matched on the namespace the window +sets, in `~/.config/hypr/sections/decorations.lua`. A new component that wants +frosting needs its own `hl.layer_rule` and a distinct +`WlrLayershell.namespace`. Without the rule it still works, rendering flat +translucent. + +## Reloading + +| | How | +| --- | --- | +| a component's QML | quickshell hot-reloads on save; no restart | +| palette | regenerate with `udt-accent <wallpaper>`; watched, no restart | +| Hyprland binds, layer rules, autostart | `hyprctl reload` | + +Hot reload covers adding and removing windows too: the keepalive window above +was added to a running shell and took effect on save. + +`qs -p <dir>` runs one directly. `qs -p <dir> ipc call <target> <fn>` reaches a +running one, which is how `SUPER+v` opens the VM drawer. + +## Conventions + +- GPLv2 only, with the header notice in every source file. +- Commits carry the reasoning, not just the change: several of the notes above + exist because a commit message explained why something was the way it was. +- No home paths in committed files. A gitleaks hook blocks them and has been + right every time; `~` in documentation, absolute paths only in the live + Hyprland config, which is not in this repo. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..3599d0e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,7 @@ +# CLAUDE.md + +This file is intentionally thin. AGENTS.md is the single source of truth for +this project, shared across every agent tool. Do not duplicate content here, +edit AGENTS.md instead. + +@AGENTS.md |
