feat(home): add satty for screenshot annotation
All checks were successful
Check / eval (push) Successful in 3m1s

Added satty (Wayland-native screenshot annotation tool) and integrated it with the Capture flow.
Wired `$mod SHIFT, Print` to slurp a region and open satty.
Added "Annotate region" to the rofi Capture menu (Tools > Capture).
Added satty's configuration via home-manager to inject the active theme's palette colors into its UI.

Verified: V1 (flake check --no-build, home activation package build).
Pending: V3 hardware/visual check for the satty UI (queued in HARDWARE-QUEUE.md).
This commit is contained in:
Bernardo Magri
2026-07-08 21:49:06 +01:00
parent 3dcbb2b0b6
commit 1d8c1a4314
7 changed files with 48 additions and 14 deletions

View File

@@ -335,20 +335,6 @@ implement. Bernardo moves accepted items into a tier.*
activation package alone (the surface most bumps touch). Does not
replace item 20; it raises the floor until item 20 lands.
- **[usefulness] Screenshot annotation step (satty)** (surfaced by the
2026-07-08 usefulness survey, iteration #71). The capture suite is rich
(region/screen → clipboard or timestamped file, OCR, recording) but has
**no annotate step** — you can't arrow/box/blur/crop before sharing,
the single common workstation gap left. Add `satty` (Wayland-native,
themeable) and an "annotate" path: e.g. `grim -g "$(slurp)" - | satty
--filename -` with save-to-`~/Pictures/Screenshots` + copy-to-clipboard
actions, wired as a Print-family keybind (SUPER+SHIFT+Print, or a
Tools ▸ Capture ▸ "Annotate region" row) with the cheatsheet entry.
Cost: small — one package + one keybind/menu row + satty theming to the
palette (its config takes colors). Verifiable to V1 headlessly (build +
bind renders); the annotate UI itself is V3-visual (queue it). Check
whether satty's palette knobs are enough to keep it on-theme or if it
needs a generated config file like the other surfaces.
## Decisions `[human]`

View File

@@ -312,6 +312,12 @@ QA machine), the **T14s** (webcam case).
Same on a whole-swap bar (summer/boreal/executive-slate). If calcurse
was removed from home.packages, the click toasts "calcurse isn't
installed" instead of doing nothing.
- [ ] **Screenshot annotation (satty)** (iteration #73) — after `home-update`:
hit SUPER+SHIFT+Print (or Tools ▸ Capture ▸ Annotate region) → a region
select (slurp) appears, then the `satty` UI opens in fullscreen with the
screenshot loaded. Check that the UI draws on the current theme palette
(tools colored properly) and hitting save places the screenshot in
`~/Pictures/Screenshots/` while hitting copy places it in the clipboard.
## AMD dev box only
- [ ] **AMD runtime bits** — VA-API (`vainfo` → radeonsi), amd-pstate EPP

View File

@@ -17,6 +17,13 @@ Template:
---
## 2026-07-08 — Screenshot annotation step (iteration #73)
- **Task:** PROPOSED item — add `satty` for annotating screenshots.
- **Did:** Added `satty` to packages with a themed `config.toml`. Bound `$mod SHIFT, Print` to start `satty` directly on a region crop (`slurp`), and added "Annotate region" to the rofi Capture menu.
- **Verified:** V1 (build tested `homeConfigurations.nomarchy.activationPackage`).
- **Pending:** V3 queued in HARDWARE-QUEUE.md to verify `satty` theming and copy/save functionality.
- **Next suggestion:** wait for Bernardo to clear `[human]` / `[blocked:hw]` bottlenecks or tackle the stability PROPOSED item.
## 2026-07-08 — home.stateVersion overridable (iteration #72)
- **Task:** PROPOSED item — `home.stateVersion` should be `mkDefault` to support migrations.
- **Did:** Changed `home.stateVersion = "26.05"` to `lib.mkDefault "26.05"` in `modules/home/default.nix`.

View File

@@ -27,6 +27,7 @@
./mime.nix # default applications (mimeapps.list), degrades with the suite
./recording.nix # nomarchy-record: screen recording behind Capture + the bar ⏺
./battery-notify.nix # low-battery toasts at the bar's 25/10% thresholds
./satty.nix # satty screenshot annotation tool, themed
];
# Clipboard history (wl-paste watcher); browsed via the SUPER+CTRL+V

View File

@@ -68,6 +68,7 @@
{ mods = ""; key = "Print"; action = "exec, grim -g \"$(slurp)\" - | wl-copy"; desc = "Screenshot region clipboard"; }
{ mods = "SHIFT"; key = "Print"; action = "exec, f=$HOME/Pictures/Screenshots/$(date +%Y%m%d-%H%M%S).png; mkdir -p $HOME/Pictures/Screenshots && grim -g \"$(slurp)\" \"$f\" && notify-send \"Screenshot saved\" \"$f\""; desc = "Screenshot region file"; }
{ mods = "CTRL"; key = "Print"; action = "exec, f=$HOME/Pictures/Screenshots/$(date +%Y%m%d-%H%M%S).png; mkdir -p $HOME/Pictures/Screenshots && grim \"$f\" && notify-send \"Screenshot saved\" \"$f\""; desc = "Screenshot screen file"; }
{ mods = "$mod SHIFT"; key = "Print"; action = "exec, f=$HOME/Pictures/Screenshots/$(date +%Y%m%d-%H%M%S).png; mkdir -p $HOME/Pictures/Screenshots && grim -g \"$(slurp)\" - | satty --filename - --fullscreen --output-filename \"$f\""; desc = "Annotate region"; }
];
# Rendered only when the session has >1 layout (a comma in

View File

@@ -460,6 +460,7 @@ ${themeRows}
choice=$( {
row "Region clipboard${hintForBind "" "Print"}" applets-screenshooter
row "Region file${hintForBind "SHIFT" "Print"}" applets-screenshooter
command -v satty >/dev/null 2>&1 && row "Annotate region${hintForBind "$mod SHIFT" "Print"}" edit-image
row "Full screen clipboard" camera-photo
row "Full screen file${hintForBind "CTRL" "Print"}" camera-photo
command -v tesseract >/dev/null 2>&1 && row "OCR region clipboard" scanner
@@ -482,6 +483,7 @@ ${themeRows}
*"Region clipboard"*) grim -g "$(slurp)" - | wl-copy ;;
*"Region file"*) mkdir -p "$dir"; grim -g "$(slurp)" "$file" \
&& notify-send "Screenshot saved" "$file" ;;
*"Annotate region"*) mkdir -p "$dir"; grim -g "$(slurp)" - | satty --filename - --fullscreen --output-filename "$file" ;;
*"OCR region"*)
# Select screenshot tesseract clipboard. Esc in slurp
# cancels silently (the recording.nix pattern); recognizing

31
modules/home/satty.nix Normal file
View File

@@ -0,0 +1,31 @@
{ config, lib, pkgs, ... }:
let
cfg = config.nomarchy;
t = cfg.theme;
c = t.colors;
in
{
config = lib.mkIf (pkgs.lib.meta.availableOn pkgs.stdenv.hostPlatform pkgs.satty) {
home.packages = [ pkgs.satty ];
xdg.configFile."satty/config.toml".text = ''
[general]
# Set the default tool to pointer or arrow?
initial-tool = "arrow"
copy-command = "wl-copy"
# Hitting copy also saves? Let the user hit save if they want to save.
# save-after-copy = false
[color-palette]
palette = [
"${c.accent}ff",
"${c.bad}ff",
"${c.warn}ff",
"${c.good}ff",
"${c.text}ff",
"${c.base}ff"
]
'';
};
}