7a5a276efd
Both plans were generated during their respective implementation runs but never committed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
341 lines
12 KiB
Markdown
341 lines
12 KiB
Markdown
# Flameshot Screenshot Swap Implementation Plan
|
|
|
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
|
|
**Goal:** Replace the bespoke `scripts/screenshot.sh` pipeline with Flameshot, bound to `Mod+Print`.
|
|
|
|
**Architecture:** Pure tool swap. Install Flameshot from `extra`, generate a small `~/.config/flameshot/flameshot.ini` from `install.sh` (mirrors the existing `mako/config` generator pattern), point `Mod+Print` at `flameshot gui`, then delete the old script + symlink + install.sh entry. Tasks ordered so `Mod+Print` keeps working at every commit boundary.
|
|
|
|
**Tech Stack:** flameshot (Qt6, official Arch `extra`), niri, bash for `install.sh`.
|
|
|
|
**Spec:** `docs/superpowers/specs/2026-05-02-flameshot-screenshot-design.md`
|
|
|
|
**Verification model:** Bash + system commands. Each task ends with shell verification commands and a one-line user check (e.g. "press `Mod+Print`, confirm Flameshot toolbar appears"). The controller has a display; subagents do not — defer visual checks to the controller.
|
|
|
|
---
|
|
|
|
## File Structure
|
|
|
|
| File | Change |
|
|
|---|---|
|
|
| `packages.txt` | add `flameshot` |
|
|
| `install.sh` | remove the `ln -sf ".../screenshot.sh" ...` line; add a flameshot.ini generator block (idempotent: only writes if file doesn't exist) |
|
|
| `niri/config.kdl` | change `Mod+Print { spawn "screenshot"; }` to `Mod+Print { spawn "flameshot" "gui"; }` |
|
|
| `scripts/screenshot.sh` | deleted |
|
|
| `~/.local/bin/screenshot` | symlink removed (filesystem only, not git-tracked) |
|
|
| `~/.config/flameshot/flameshot.ini` | created on disk by the install.sh block (filesystem only, not git-tracked) |
|
|
|
|
---
|
|
|
|
## Task 1: Install Flameshot and add to packages.txt
|
|
|
|
After this task, the `flameshot` binary is on PATH and `packages.txt` declares it as a dependency. The old screenshot script and keybind are still wired up — nothing functional has changed yet.
|
|
|
|
**Files:**
|
|
- Modify: `packages.txt` (add one line)
|
|
|
|
- [ ] **Step 1: Install flameshot via the AUR helper**
|
|
|
|
```bash
|
|
yay -S --needed --noconfirm flameshot
|
|
```
|
|
|
|
Expected: package installs (or "is up to date" if already present). If `yay` is unavailable, substitute `paru` or `sudo pacman -S --needed --noconfirm flameshot`.
|
|
|
|
- [ ] **Step 2: Verify the binary is on PATH**
|
|
|
|
```bash
|
|
flameshot --version
|
|
```
|
|
|
|
Expected: a version string like `Flameshot v13.3.0 (compiled with Qt 6.x)`. If "command not found", the install failed — escalate.
|
|
|
|
- [ ] **Step 3: Add `flameshot` to `packages.txt`**
|
|
|
|
Open `packages.txt` and insert `flameshot` in alphabetical-ish order. The existing list is roughly grouped by topic, not strictly sorted. Insert after `fw-fanctrl` (line 39) so it sits with the small one-off utilities cluster:
|
|
|
|
```
|
|
fw-fanctrl
|
|
satty
|
|
starship
|
|
flameshot
|
|
```
|
|
|
|
(Final order doesn't matter as long as `flameshot` appears once and on its own line. Don't reorder unrelated lines.)
|
|
|
|
- [ ] **Step 4: Verify packages.txt is well-formed**
|
|
|
|
```bash
|
|
grep -c "^flameshot$" packages.txt
|
|
```
|
|
|
|
Expected: `1` (exactly one occurrence).
|
|
|
|
- [ ] **Step 5: Commit**
|
|
|
|
```bash
|
|
git add packages.txt
|
|
git commit -m "packages: add flameshot"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 2: Add flameshot config generator to install.sh and run it
|
|
|
|
After this task, `~/.config/flameshot/flameshot.ini` exists with the spec's defaults. Re-running `install.sh` will not clobber the file (the generator has an `[ ! -f ]` guard so user-saved preferences like `savePath` are preserved on subsequent runs). The screenshot keybind still points at the old script.
|
|
|
|
**Files:**
|
|
- Modify: `install.sh` (insert generator block after the existing mako python block, around line 42)
|
|
|
|
- [ ] **Step 1: Insert the flameshot config generator into `install.sh`**
|
|
|
|
Find the existing mako block in `install.sh`. It looks like:
|
|
|
|
```bash
|
|
python3 - <<'PYEOF'
|
|
import json, os
|
|
c = json.load(open("theme/colors.json"))
|
|
config = f"""background-color={c['background']}
|
|
text-color={c['foreground']}
|
|
border-size=2
|
|
border-color={c['blue']}
|
|
default-timeout=4000
|
|
"""
|
|
open(os.path.expanduser("~/.config/mako/config"), "w").write(config)
|
|
PYEOF
|
|
```
|
|
|
|
Immediately *after* the `PYEOF` line that closes the mako block, insert:
|
|
|
|
```bash
|
|
mkdir -p ~/.config/flameshot
|
|
if [ ! -f ~/.config/flameshot/flameshot.ini ]; then
|
|
cat > ~/.config/flameshot/flameshot.ini <<'INI'
|
|
[General]
|
|
disabledTrayIcon=true
|
|
showStartupLaunchMessage=false
|
|
showHelp=false
|
|
copyAndCloseAfterUpload=true
|
|
uiColor=#81a2be
|
|
contrastUiColor=#1d1f21
|
|
contrastOpacity=190
|
|
INI
|
|
fi
|
|
```
|
|
|
|
The `[ ! -f ]` guard is required: Flameshot writes runtime state (savePath, last folder) back to this file, so re-running `install.sh` must not overwrite user preferences.
|
|
|
|
- [ ] **Step 2: Sanity-check `install.sh` parses as bash**
|
|
|
|
```bash
|
|
bash -n install.sh
|
|
```
|
|
|
|
Expected: no output, exit 0. (`-n` is dry-run syntax check.)
|
|
|
|
- [ ] **Step 3: Run the new block manually to create the live config**
|
|
|
|
You can either run install.sh in full, or extract just the new block. Cleanest is to run the block standalone:
|
|
|
|
```bash
|
|
mkdir -p ~/.config/flameshot
|
|
if [ ! -f ~/.config/flameshot/flameshot.ini ]; then
|
|
cat > ~/.config/flameshot/flameshot.ini <<'INI'
|
|
[General]
|
|
disabledTrayIcon=true
|
|
showStartupLaunchMessage=false
|
|
showHelp=false
|
|
copyAndCloseAfterUpload=true
|
|
uiColor=#81a2be
|
|
contrastUiColor=#1d1f21
|
|
contrastOpacity=190
|
|
INI
|
|
fi
|
|
```
|
|
|
|
- [ ] **Step 4: Verify the file was written with the right contents**
|
|
|
|
```bash
|
|
cat ~/.config/flameshot/flameshot.ini
|
|
```
|
|
|
|
Expected output:
|
|
```
|
|
[General]
|
|
disabledTrayIcon=true
|
|
showStartupLaunchMessage=false
|
|
showHelp=false
|
|
copyAndCloseAfterUpload=true
|
|
uiColor=#81a2be
|
|
contrastUiColor=#1d1f21
|
|
contrastOpacity=190
|
|
```
|
|
|
|
- [ ] **Step 5: Verify the guard works (re-run is a no-op)**
|
|
|
|
```bash
|
|
# Mutate the file slightly
|
|
echo "savePath=/home/alex/Pictures" >> ~/.config/flameshot/flameshot.ini
|
|
# Re-run the generator block (paste from Step 3)
|
|
mkdir -p ~/.config/flameshot
|
|
if [ ! -f ~/.config/flameshot/flameshot.ini ]; then
|
|
cat > ~/.config/flameshot/flameshot.ini <<'INI'
|
|
[General]
|
|
disabledTrayIcon=true
|
|
showStartupLaunchMessage=false
|
|
showHelp=false
|
|
copyAndCloseAfterUpload=true
|
|
uiColor=#81a2be
|
|
contrastUiColor=#1d1f21
|
|
contrastOpacity=190
|
|
INI
|
|
fi
|
|
# Confirm the savePath line is still present (file was not regenerated)
|
|
grep "^savePath=" ~/.config/flameshot/flameshot.ini
|
|
```
|
|
|
|
Expected: `savePath=/home/alex/Pictures` (proves the `[ ! -f ]` guard prevented overwrite).
|
|
|
|
Clean up the test mutation (so the file matches the spec's defaults again):
|
|
|
|
```bash
|
|
sed -i '/^savePath=/d' ~/.config/flameshot/flameshot.ini
|
|
```
|
|
|
|
- [ ] **Step 6: Commit**
|
|
|
|
```bash
|
|
git add install.sh
|
|
git commit -m "install: generate flameshot.ini with idempotent guard"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 3: Repoint `Mod+Print` to Flameshot
|
|
|
|
After this task, pressing `Mod+Print` opens Flameshot's GUI (region selector + on-canvas annotation toolbar). The old `scripts/screenshot.sh` is no longer reachable via keybind, but the script and its symlink still exist on disk — Task 4 deletes them.
|
|
|
|
**Files:**
|
|
- Modify: `niri/config.kdl` (line 87)
|
|
|
|
- [ ] **Step 1: Replace the keybind**
|
|
|
|
In `niri/config.kdl`, find line 87:
|
|
|
|
```kdl
|
|
Mod+Print { spawn "screenshot"; }
|
|
```
|
|
|
|
Replace with:
|
|
|
|
```kdl
|
|
Mod+Print { spawn "flameshot" "gui"; }
|
|
```
|
|
|
|
Note the two-string form for `spawn` — niri's `spawn` action takes the program and each argument as separate quoted strings. `spawn "flameshot gui"` (single string) would not work; niri would try to exec a binary literally named `flameshot gui`.
|
|
|
|
- [ ] **Step 2: Validate the niri config**
|
|
|
|
```bash
|
|
niri validate
|
|
```
|
|
|
|
Expected: exit 0 and a final line `INFO niri: config is valid`. Any "ERROR" or non-zero exit means a syntax issue — fix before continuing.
|
|
|
|
- [ ] **Step 3: User-side visual verification (controller only — subagent skip)**
|
|
|
|
Niri picks up `config.kdl` changes live; no reload needed. Press `Mod+Print`. Expected: Flameshot's region-selector overlay appears, with a floating toolbar showing drawing tools and Save/Copy/Discard buttons. Cancel out (Esc) without taking a real screenshot.
|
|
|
|
If a portal permission prompt appears the first time, allow it — Flameshot uses `xdg-desktop-portal-wlr` to capture under Wayland.
|
|
|
|
If `Mod+Print` does nothing or you see "command not found" in `journalctl --user`, the binary isn't on PATH for niri — re-run Task 1, Step 1.
|
|
|
|
- [ ] **Step 4: Commit**
|
|
|
|
```bash
|
|
git add niri/config.kdl
|
|
git commit -m "niri: bind Mod+Print to flameshot gui"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 4: Delete the old screenshot script, symlink, and install.sh entry
|
|
|
|
After this task, all traces of `scripts/screenshot.sh` are gone — script file deleted, `~/.local/bin/screenshot` symlink removed, and the corresponding line in `install.sh` removed so re-running it doesn't recreate the dead symlink. `Mod+Print` continues to work via Flameshot.
|
|
|
|
**Files:**
|
|
- Delete: `scripts/screenshot.sh`
|
|
- Modify: `install.sh` (remove one line)
|
|
- Filesystem: `~/.local/bin/screenshot` (remove symlink)
|
|
|
|
- [ ] **Step 1: Remove the symlink line from `install.sh`**
|
|
|
|
In `install.sh`, find this line (it's inside the `==> Installing scripts` section, around line 61):
|
|
|
|
```bash
|
|
ln -sf "$(pwd)/scripts/screenshot.sh" ~/.local/bin/screenshot
|
|
```
|
|
|
|
Delete the entire line. The surrounding lines (other `ln -sf` calls for the remaining scripts) stay intact.
|
|
|
|
- [ ] **Step 2: Sanity-check install.sh still parses**
|
|
|
|
```bash
|
|
bash -n install.sh
|
|
```
|
|
|
|
Expected: no output, exit 0.
|
|
|
|
- [ ] **Step 3: Delete the live symlink**
|
|
|
|
```bash
|
|
rm ~/.local/bin/screenshot
|
|
```
|
|
|
|
Expected: silent success. Verify it's gone:
|
|
|
|
```bash
|
|
ls -la ~/.local/bin/screenshot 2>&1
|
|
```
|
|
|
|
Expected: `cannot access ... No such file or directory`.
|
|
|
|
- [ ] **Step 4: Delete the script file from the repo**
|
|
|
|
```bash
|
|
git rm scripts/screenshot.sh
|
|
```
|
|
|
|
Expected: `rm 'scripts/screenshot.sh'`.
|
|
|
|
- [ ] **Step 5: Verify nothing else in the repo references the deleted script**
|
|
|
|
```bash
|
|
grep -rn "screenshot" --include="*.kdl" --include="*.sh" --include="*.jsonc" --include="*.toml" --include="*.fish" --exclude-dir=docs /home/alex/Documents/dotfiles
|
|
```
|
|
|
|
Expected: zero hits, or only matches inside markdown/spec files (which the include-glob excludes anyway). If the keybind from Task 3 still says `spawn "screenshot"`, Task 3 didn't land — go back and check.
|
|
|
|
- [ ] **Step 6: Confirm `Mod+Print` still works (controller only — subagent skip)**
|
|
|
|
Press `Mod+Print`. Flameshot's GUI should still appear (this isn't a regression test — it's just a sanity check that nothing in the cleanup broke the live keybind).
|
|
|
|
- [ ] **Step 7: Commit**
|
|
|
|
```bash
|
|
git add install.sh scripts/screenshot.sh
|
|
git commit -m "screenshot: remove old grim/slurp/wofi pipeline (replaced by flameshot)"
|
|
```
|
|
|
|
(`git rm` from Step 4 already staged the deletion; this commit picks up both the staged deletion and the install.sh edit.)
|
|
|
|
---
|
|
|
|
## Final verification
|
|
|
|
- [ ] **Pressing `Mod+Print` opens Flameshot.** Region selector + on-canvas toolbar with drawing tools and Save/Copy/Discard buttons.
|
|
- [ ] **`flameshot gui` produces a usable capture.** Pick a region, click Copy → confirm clipboard has the image (`wl-paste --list-types | grep image/png` should show `image/png`). Click Save → file lands wherever Flameshot prompts (first-time prompt expected; pick `~/Pictures`).
|
|
- [ ] **No leftover references.** `grep -rn "screenshot\.sh\|/local/bin/screenshot" /home/alex/Documents/dotfiles --exclude-dir=.git --exclude-dir=docs` → no hits.
|
|
- [ ] **install.sh is re-runnable without breakage.** Optional: rerun `bash install.sh` and confirm flameshot.ini is preserved (the `[ ! -f ]` guard) and no `~/.local/bin/screenshot` symlink reappears (because the line was removed).
|
|
- [ ] **Toolbar colors match the theme.** The Flameshot floating toolbar should show the Tomorrow Night blue accent (`#81a2be`) on the dark background (`#1d1f21`).
|