A setting changed through mesh-controller.settings rewrote dunstrc, but the running dunst kept the old font and width until the next login. Declare the package's dunst.service in the account's manager, without a state, with reload-on the configuration, so the node-engine runs its ExecReload (dunstctl reload) and what is on screen stays. Add dunst_reload to do the same on demand and say the font and width the files set.
97 lines
5.9 KiB
Markdown
97 lines
5.9 KiB
Markdown
# dunst
|
|
|
|
The notifier as a module (novox/hq ADR 0208, research 026/05).
|
|
|
|
- Installs `dunst`, and `libnotify` for `notify-send`, the client every program and these tools use.
|
|
- Claims the mesh's `node-notifier` seat and serves its verbs `send` and `history`.
|
|
- Owns `~/.config/dunst/dunstrc` and the directory `~/.config/dunst/dunstrc.d/`. Another module's
|
|
rule is that module's own file in the directory (ADR 0208 §4). dunst reads the directory after
|
|
`dunstrc`, so a drop-in outranks it.
|
|
- **Starts nothing.** The package registers dunst with D-Bus, which starts it on the first
|
|
notification, inside the account's service manager. There is no autostart line and no
|
|
session-start contribution. The package's own `dunst.service` is declared without a state, in the
|
|
account's manager (`scope: user`, ADR 0177), only so the node-engine can reload it: when the mesh
|
|
rewrites `dunstrc`, a running dunst is told to read it again (`reload-on`, the unit's
|
|
`ExecReload=dunstctl reload`). A dunst that is not running is left alone and reads the file when the bus
|
|
starts it (ADR 0117).
|
|
- **Requires no display of its own.** dunst speaks both X11 and Wayland and picks the one the session
|
|
has, so it serves an X session and a later sway one alike.
|
|
|
|
## Answers from a notification
|
|
|
|
`send` with `actions` runs `notify-send --wait` with one `--action` per answer, answers the id at once and
|
|
waits in this bundle for the operator's choice (dunst offers the actions on a middle click, or in its
|
|
context menu). The token chosen is said as this module's event `action-chosen`; it becomes the
|
|
node-notifier seat's event once seats publish events of their own (novox/hq to-be 46 phase 3). Nothing
|
|
is said for a notification closed, expired or replaced without an answer, and a wait ends after seven
|
|
days. A notification that offers answers stays until dismissed (`expire_ms` 0). A restart of this bundle
|
|
ends the waits it held; it says `started` {machine} once it serves, and the operator channel shows the
|
|
open answers there again (novox/hq ADR 0258). `notify-send` prints the id before it waits, also into a
|
|
pipe (checked on the laptop on 2026-10-08: the id at once, and "Wait timeout expired" when it expired).
|
|
|
|
## Tools
|
|
|
|
Every tool goes over the account's session bus. None needs the screen, and each answers clearly when
|
|
the account is not logged in.
|
|
|
|
| tool | does |
|
|
|---|---|
|
|
| `node-notifier.send` | a notification: title, body, urgency, sender, icon, how long, and the answers it offers (`actions`: token and label); answers its id, and says the chosen answer later as the event `action-chosen` {id, token, machine} |
|
|
| `node-notifier.history` | what was shown, newest first, with how long ago |
|
|
| `dunst_pause` / `dunst_resume` | do not disturb: notifications are held back, not lost |
|
|
| `dunst_close_all` | clear the screen; the history keeps them |
|
|
| `dunst_rules` | the rules the running notifier holds, and the files they come from |
|
|
| `dunst_count` | shown, waiting, in history, and whether paused |
|
|
| `dunst_reload` | read the configuration again now, keeping what is shown; answers the files read and the font, font size and width they set, with the file each came from (dunst does not say its settings over the bus, so these are read from the same files) |
|
|
|
|
## Settings
|
|
|
|
Two preferences have defaults in the definition (novox/hq ADR 0262). The mesh's layer, then a machine's,
|
|
overrides them, and the file is written with the value, never with a variable dunst reads.
|
|
|
|
| setting | default | what it is |
|
|
|---|---|---|
|
|
| `font-size` | 10 | the points of `font = Inter <size>`; 10 reads well on a screen of about 100 DPI, which is the workstations |
|
|
| `width` | 250 | the notification's width in pixels; a larger font needs a wider notification |
|
|
|
|
A machine with a denser screen sets both for itself, and the next push writes them:
|
|
|
|
mesh-controller.settings {module: "dunst", node: "<machine>", values: '{"font-size": 16, "width": 400}'}
|
|
|
|
`mesh-controller.settings {module: "dunst", node: "<machine>"}` shows each value and where it came from:
|
|
the default, the mesh, or the machine. When the push rewrites `dunstrc`, the node-engine reloads the
|
|
running dunst, so the next notification is drawn at the new size, without a login. A reload keeps the
|
|
notifications on screen and in the history; a restart would drop them, which is why this is a reload.
|
|
|
|
## What it chose, and what it improves
|
|
|
|
The workstations' files differed: one had the notifications bottom-right, 15 % transparent and with
|
|
rounded corners; the other top-right, opaque and square. This module takes the second, because the
|
|
rest of the desktop is square and opaque, and the top-right corner sits under the bar that shows the
|
|
count. The file keeps only the settings that differ from dunst's defaults.
|
|
|
|
- **The context menu works.** It called `/usr/bin/dmenu`, installed on neither machine. It now calls
|
|
`dmenu`, the seat command of whichever module holds `node-launcher` (`rofi` on the workstations).
|
|
- **The face is the interface one,** Inter (research 026/04), instead of a monospace Nerd font.
|
|
- `icon_path`, which named two directories of an icon theme that is not installed, is gone. The icon
|
|
theme is looked up recursively.
|
|
|
|
## What it leaves as found
|
|
|
|
- `~/.config/dunst/dunstrc.d/50-slack.conf`, the Slack rule. It becomes the Slack module's own drop-in
|
|
when there is one, and until then it is the operator's file in a directory this module owns.
|
|
|
|
## Migration (ADR 0182)
|
|
|
|
- The first push keeps the found `dunstrc` once, then writes the module's.
|
|
- **The desktop runs two notification daemons** because its session began before the session bus
|
|
fix (research 026/01). That ends at the next login, and nothing here starts a second one.
|
|
`dunst_count` after logging in again shows the one daemon's counts.
|
|
|
|
## Blockers
|
|
|
|
- `node-notifier` is ADR 0208's seat. Until the controller knows it, `mctl` reads the claim as
|
|
unknown.
|
|
- `dunst_rules` and the counts ask the running notifier. When none runs, the bus starts one, which
|
|
needs a session to draw on.
|