diff options
Diffstat (limited to 'docs/superpowers/specs/2026-10-23-companion-blush-design.md')
| -rw-r--r-- | docs/superpowers/specs/2026-10-23-companion-blush-design.md | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/docs/superpowers/specs/2026-10-23-companion-blush-design.md b/docs/superpowers/specs/2026-10-23-companion-blush-design.md new file mode 100644 index 0000000..3ef8c9d --- /dev/null +++ b/docs/superpowers/specs/2026-10-23-companion-blush-design.md @@ -0,0 +1,74 @@ +# Companion: blushing at a wallpaper + +She turns to look at the wallpaper behind her and blushes, for the +wallpapers on a list, when the workspace in front of her is empty enough +for her to see it. + +## Trigger + +Checked at two moments, in `Companion.qml`: + +- the focused workspace changes or loses a window (`workspacev2`, + `closewindow`), so switching to an empty workspace or closing its last + window counts; +- she stops being away: shown (SUPER+\ or the settings switch), back + from a remap after another layer opened, moved to another monitor with + the focus, back from a dodge, or out of fullscreen. + +It fires when all three hold: + +- the focused workspace has no windows (`toplevels.values.length === 0`, + after `Hyprland.refreshToplevels()`); +- the wallpaper on her monitor is on the list; +- at least 3 minutes since the last blush (`T.admireCooldown`). + +Her monitor's wallpaper: wallp's `wallp.conf` maps `OUTPUT_H` and +`OUTPUT_V` to connectors, and `Wallpapers.currentH`/`currentV` say what is +on each. The connector names are read from `wallp.conf`, not hardcoded. A +monitor matching neither has no wallpaper and never fires. + +## Reaction + +A new state in `Mood.js`, `admire`, stamped by `admireAt`: + +| since `admireAt` | frame | +| --- | --- | +| 0 to 1.5 s (`T.admireLook`) | `watch`, the back view: she turns to the wallpaper | +| 1.5 to 4.5 s (`T.admireBlush`) | `blush3` | + +`watch` and `blush3` exist in both outfits, so no new art is generated. + +Priority: below destruct, scorched, dodge, shoved, listen, think, wave and +clicks; above mock, watch (typing), stretch, muse and idle. A click during +it wins, as it does over everything below it now. + +A line from a `wallpaper` set in `Lines.js` as the blush starts, under the +usual 30 s line cooldown. + +## The list + +A plain text file: one absolute path per line, blank lines and lines +starting with `#` skipped. Paths compare exactly with what wallp writes to +`wall_h`/`wall_v`. + +- Default path `~/.config/keystone/companion-blush.txt`; a missing file is + an empty list. +- The path is `Prefs.companionBlushFile`, with a text field on Settings > + Desktop > Companion (`desktop/modules/companion/`). +- Watched with a `FileView`, so a hand edit applies live. +- The wallpaper picker (`WallpaperTab.qml`) draws a heart toggle on each + thumbnail, filled when the path is listed. Toggling rewrites the file + through a `Process` running `cat > <file>`, because + `FileView.setText("")` on an emptied list writes no file (AGENTS.md). + Comments in the file are kept on rewrite; only the toggled path's line is + added or removed. + +The parsed list lives in one place both the companion and the picker read, +a small singleton in `desktop/companion/`. + +## Check + +`test_mood.js` gains: the `watch` then `blush3` sequence and its end, the +3 minute cooldown, a click winning over it, and it winning over typing. +The trigger is checked by hand: an empty workspace with a listed +wallpaper, a non-empty one, an unlisted wallpaper, each monitor. |
