From fceeb5dc23c5e5a951f725e7682eab6814191c47 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Tue, 15 Sep 2026 12:25:21 +0200 Subject: docs(status): document the module and record its traps A FileView fires its own fileChanged on setText, so a handler that writes in response to a change loops unless it compares first. IdleInhibitor has no window of its own and does nothing without one, so the singleton is handed the keepalive window by shell.qml. Both were read from the documentation while designing and confirmed while implementing. --- desktop/modules/status/README.md | 59 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 desktop/modules/status/README.md (limited to 'desktop') diff --git a/desktop/modules/status/README.md b/desktop/modules/status/README.md new file mode 100644 index 0000000..0bb376f --- /dev/null +++ b/desktop/modules/status/README.md @@ -0,0 +1,59 @@ +# status + +Desktop modes as state: `dnd` and `presentation`, owned by the `Status` +singleton and stored as files under `$XDG_RUNTIME_DIR`. + +## The files are the interface + + $XDG_RUNTIME_DIR/status.dnd + $XDG_RUNTIME_DIR/status.presentation + +Each holds `0` or `1`; a missing file means off. That directory is tmpfs, so a +reboot resets every mode and there is no cleanup code. A shell restart does +not: the files outlive the process and the singleton reads them back. + +Anything can read a mode with `cat`. `statusctl` is the convenience, not the +mechanism, which is why it keeps working while quickshell is down. + +## statusctl + + statusctl get prints 0 or 1 + statusctl set 0|1 + statusctl toggle + statusctl watch waybar JSON on every change + +The repo copy is the source; the user installs it to `~/bin`. `watch` watches +the directory rather than the file, because an atomic write replaces the file +and a watch on the old inode dies with it. + +Setting a mode with `statusctl` records the state without firing its effects. +The shell sees the change through its own `FileView` watch and asserts them, +so the effects follow either way. If the shell is down, the state is recorded +and reasserted when it returns. + +## Effects + +`dnd` has none of its own. It is state the notification daemon reads. + +`presentation` sets `dnd`, asserts a Wayland idle inhibitor, and pauses +breaktimer. Turning it off restores `dnd` to the value it had before rather +than clearing it, so hand-set DND survives a presentation. + +breaktimer owns `$XDG_RUNTIME_DIR/breaktimer.state`. This module calls +`breaktimer.sh pause|resume` and never writes that file: its daemon loop +rewrites it on every phase change, and two writers would race. + +## Waybar + +`custom/presentation` reads `statusctl presentation watch`. It replaces +waybar's built-in `idle_inhibitor`, which cannot be kept alongside it: that +module owns its own inhibitor object, so both would have to be released +before the screen could lock. + +## The check + + ./test-statusctl.sh + +Points `XDG_RUNTIME_DIR` at a temporary directory, so it never touches live +modes. Covers the file format, the atomic write, the toggle, the unknown-mode +error and both watch states. -- cgit v1.2.3