Compare commits
5 Commits
8a087d123f
...
d923cfb5cf
| Author | SHA1 | Date | |
|---|---|---|---|
| d923cfb5cf | |||
| b2c2f2d394 | |||
| a8650c2c86 | |||
| a6ed78846b | |||
| 5639219d9f |
@@ -0,0 +1,216 @@
|
||||
# Interactive Screenshot Script 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:** Rewrite `scripts/screenshot.sh` so that after capture a mako notification appears with an "Actions" button that opens a wofi dmenu picker (swappy, satty, imv, copy path, delete).
|
||||
|
||||
**Architecture:** Single bash script. Capture → clipboard → blocking `notify-send --action` → if "Actions" clicked, pipe options into `wofi --dmenu` → execute chosen action. No new files beyond the script itself.
|
||||
|
||||
**Tech Stack:** bash, grim, slurp, wl-copy, notify-send (libnotify), wofi, swappy, satty, imv
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Add satty and swappy to packages.txt
|
||||
|
||||
**Files:**
|
||||
- Modify: `packages.txt`
|
||||
|
||||
- [ ] **Step 1: Append the two packages**
|
||||
|
||||
Open `packages.txt` and add these two lines at the end:
|
||||
|
||||
```
|
||||
satty
|
||||
swappy
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Verify**
|
||||
|
||||
```bash
|
||||
grep -E "satty|swappy" packages.txt
|
||||
```
|
||||
|
||||
Expected output:
|
||||
```
|
||||
satty
|
||||
swappy
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add packages.txt
|
||||
git commit -m "packages: add satty and swappy"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Rewrite screenshot.sh
|
||||
|
||||
**Files:**
|
||||
- Modify: `scripts/screenshot.sh`
|
||||
|
||||
- [ ] **Step 1: Write the new script**
|
||||
|
||||
Replace the full contents of `scripts/screenshot.sh` with:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
FILE="$HOME/Pictures/screenshot-$(date +%s).png"
|
||||
|
||||
# Exit silently if the user cancels region selection
|
||||
if ! grim -g "$(slurp)" "$FILE"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
wl-copy < "$FILE"
|
||||
|
||||
action=$(notify-send "Screenshot captured" \
|
||||
"Saved · Copied to clipboard" \
|
||||
--hint="string:image-path:$FILE" \
|
||||
--expire-time=10000 \
|
||||
--action="actions=Actions")
|
||||
|
||||
[[ "$action" != "actions" ]] && exit 0
|
||||
|
||||
choice=$(printf 'Annotate with swappy\nAnnotate with satty\nOpen in imv\nCopy path\nDelete' \
|
||||
| wofi --dmenu --prompt "Screenshot")
|
||||
|
||||
case "$choice" in
|
||||
"Annotate with swappy")
|
||||
swappy -f "$FILE" &
|
||||
;;
|
||||
"Annotate with satty")
|
||||
satty --filename "$FILE" &
|
||||
;;
|
||||
"Open in imv")
|
||||
imv "$FILE" &
|
||||
;;
|
||||
"Copy path")
|
||||
printf '%s' "$FILE" | wl-copy
|
||||
notify-send "Path copied" "$FILE"
|
||||
;;
|
||||
"Delete")
|
||||
rm "$FILE"
|
||||
notify-send "Screenshot deleted" "File removed"
|
||||
;;
|
||||
esac
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Ensure it is executable**
|
||||
|
||||
```bash
|
||||
chmod +x scripts/screenshot.sh
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Verify the symlink still points to the right place**
|
||||
|
||||
```bash
|
||||
ls -la ~/.local/bin/screenshot
|
||||
```
|
||||
|
||||
Expected: symlink pointing to `.../dotfiles/scripts/screenshot.sh`. If it is missing, run:
|
||||
|
||||
```bash
|
||||
ln -sf "$(pwd)/scripts/screenshot.sh" ~/.local/bin/screenshot
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add scripts/screenshot.sh
|
||||
git commit -m "screenshot: add post-capture notification and wofi action picker"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Smoke test
|
||||
|
||||
No Wayland-aware unit test framework is available, so verification is manual. Run through each path once.
|
||||
|
||||
- [ ] **Step 1: Basic capture → dismiss**
|
||||
|
||||
```bash
|
||||
screenshot
|
||||
```
|
||||
|
||||
- Select a region with slurp.
|
||||
- Notification appears: "Screenshot captured / Saved · Copied to clipboard".
|
||||
- Dismiss or wait 10 s for it to expire.
|
||||
- Expected: file exists in `~/Pictures/`, clipboard contains the image, nothing else happens.
|
||||
|
||||
```bash
|
||||
ls -t ~/Pictures/screenshot-*.png | head -1
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Cancel capture**
|
||||
|
||||
```bash
|
||||
screenshot
|
||||
```
|
||||
|
||||
- Press Escape in slurp.
|
||||
- Expected: no notification, no file created.
|
||||
|
||||
- [ ] **Step 3: Actions → swappy**
|
||||
|
||||
```bash
|
||||
screenshot
|
||||
```
|
||||
|
||||
- Select a region, click "Actions", choose "Annotate with swappy".
|
||||
- Expected: swappy opens with the screenshot loaded.
|
||||
|
||||
- [ ] **Step 4: Actions → satty**
|
||||
|
||||
```bash
|
||||
screenshot
|
||||
```
|
||||
|
||||
- Select a region, click "Actions", choose "Annotate with satty".
|
||||
- Expected: satty opens with the screenshot loaded.
|
||||
|
||||
- [ ] **Step 5: Actions → imv**
|
||||
|
||||
```bash
|
||||
screenshot
|
||||
```
|
||||
|
||||
- Select a region, click "Actions", choose "Open in imv".
|
||||
- Expected: imv opens displaying the screenshot.
|
||||
|
||||
- [ ] **Step 6: Actions → Copy path**
|
||||
|
||||
```bash
|
||||
screenshot
|
||||
```
|
||||
|
||||
- Select a region, click "Actions", choose "Copy path".
|
||||
- Expected: second notification "Path copied" fires; clipboard now contains the file path (verify with `wl-paste`).
|
||||
|
||||
```bash
|
||||
wl-paste
|
||||
```
|
||||
|
||||
- [ ] **Step 7: Actions → Delete**
|
||||
|
||||
```bash
|
||||
screenshot
|
||||
```
|
||||
|
||||
- Select a region, click "Actions", choose "Delete".
|
||||
- Expected: notification "Screenshot deleted" fires; file is gone.
|
||||
|
||||
```bash
|
||||
ls ~/Pictures/screenshot-*.png | tail -1 # should not include the just-deleted file
|
||||
```
|
||||
|
||||
- [ ] **Step 8: Actions → Escape wofi**
|
||||
|
||||
```bash
|
||||
screenshot
|
||||
```
|
||||
|
||||
- Select a region, click "Actions", then press Escape in wofi.
|
||||
- Expected: nothing happens; file and clipboard copy are preserved.
|
||||
@@ -0,0 +1,77 @@
|
||||
# Interactive Screenshot Script Design
|
||||
|
||||
**Date:** 2026-04-28
|
||||
**Status:** Approved
|
||||
|
||||
## Summary
|
||||
|
||||
Replace the current minimal screenshot script with an interactive post-capture flow: a mako notification confirms the capture and offers an "Actions" button; clicking it opens a wofi dmenu with five options. Dismissing the notification requires no further interaction.
|
||||
|
||||
## Current Behaviour
|
||||
|
||||
```bash
|
||||
FILE=~/Pictures/screenshot-$(date +%s).png
|
||||
grim -g "$(slurp)" "$FILE"
|
||||
wl-copy < "$FILE"
|
||||
```
|
||||
|
||||
Captures a region, saves to `~/Pictures/`, copies to clipboard. No feedback, no post-capture options.
|
||||
|
||||
## Flow
|
||||
|
||||
```
|
||||
slurp (region select)
|
||||
└─ cancelled (exit ≠ 0)? → exit silently
|
||||
grim → ~/Pictures/screenshot-<timestamp>.png
|
||||
wl-copy → copy image bytes to clipboard
|
||||
notify-send --wait
|
||||
title: "Screenshot captured"
|
||||
body: "Saved · Copied to clipboard"
|
||||
icon: $FILE (mako shows thumbnail)
|
||||
action: "actions:Actions"
|
||||
timeout: 10 000 ms
|
||||
└─ dismissed / timed out → done
|
||||
└─ "Actions" clicked → wofi --dmenu --prompt "Screenshot"
|
||||
├─ Annotate with swappy (default, top)
|
||||
├─ Annotate with satty
|
||||
├─ Open in imv
|
||||
├─ Copy path
|
||||
└─ Delete
|
||||
```
|
||||
|
||||
## Actions
|
||||
|
||||
| Choice | Command | Follow-up |
|
||||
|---|---|---|
|
||||
| Annotate with swappy | `swappy -f "$FILE" &` | swappy handles its own save |
|
||||
| Annotate with satty | `satty --filename "$FILE" &` | satty handles its own save |
|
||||
| Open in imv | `imv "$FILE" &` | none |
|
||||
| Copy path | `printf '%s' "$FILE" \| wl-copy` | notification: "Path copied" |
|
||||
| Delete | `rm "$FILE"` | notification: "Screenshot deleted" |
|
||||
|
||||
Annotation tools are launched in background so the script does not block waiting for them.
|
||||
|
||||
## Edge Cases
|
||||
|
||||
- **slurp cancelled:** `grim` exits non-zero; script checks `$?` and exits cleanly with no notification or file.
|
||||
- **No selection made:** same as above — slurp exits non-zero if the user escapes.
|
||||
- **wofi dismissed (Escape):** no action taken; file and clipboard copy are preserved.
|
||||
- **Delete:** immediate, no undo. A confirmation notification fires so the user knows it happened.
|
||||
|
||||
## Files Changed
|
||||
|
||||
- `scripts/screenshot.sh` — rewrite
|
||||
- `packages.txt` — add `satty`, `swappy` (already installed manually)
|
||||
|
||||
## Tools Used
|
||||
|
||||
| Tool | Purpose |
|
||||
|---|---|
|
||||
| `grim` | screen capture |
|
||||
| `slurp` | region selection |
|
||||
| `wl-copy` | clipboard |
|
||||
| `notify-send` | notification (mako daemon) |
|
||||
| `wofi --dmenu` | action picker |
|
||||
| `swappy` | annotation (default) |
|
||||
| `satty` | annotation (alternative) |
|
||||
| `imv` | image viewer |
|
||||
+2
-1
@@ -6,6 +6,7 @@ alacritty
|
||||
swww
|
||||
grim
|
||||
slurp
|
||||
swappy
|
||||
wl-clipboard
|
||||
brightnessctl
|
||||
pamixer
|
||||
@@ -36,4 +37,4 @@ file-roller
|
||||
xwayland-satellite
|
||||
power-profiles-daemon
|
||||
fw-fanctrl
|
||||
|
||||
satty
|
||||
|
||||
Regular → Executable
+40
-2
@@ -1,5 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
FILE=~/Pictures/screenshot-$(date +%s).png
|
||||
grim -g "$(slurp)" "$FILE"
|
||||
FILE="$HOME/Pictures/screenshot-$(date +%s).png"
|
||||
|
||||
mkdir -p "$HOME/Pictures"
|
||||
|
||||
# Exit silently if the user cancels region selection
|
||||
if ! grim -g "$(slurp)" "$FILE"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
wl-copy < "$FILE"
|
||||
|
||||
action=$(notify-send "Screenshot captured" \
|
||||
"Saved · Copied to clipboard" \
|
||||
--hint="string:image-path:$FILE" \
|
||||
--expire-time=10000 \
|
||||
--action="actions:Actions")
|
||||
|
||||
[[ "$action" != "actions" ]] && exit 0
|
||||
|
||||
choice=$(printf 'Annotate with swappy\nAnnotate with satty\nOpen in imv\nCopy path\nDelete' \
|
||||
| wofi --dmenu --prompt "Screenshot")
|
||||
|
||||
case "$choice" in
|
||||
"Annotate with swappy")
|
||||
swappy -f "$FILE" &
|
||||
;;
|
||||
"Annotate with satty")
|
||||
satty --filename "$FILE" &
|
||||
;;
|
||||
"Open in imv")
|
||||
imv "$FILE" &
|
||||
;;
|
||||
"Copy path")
|
||||
printf '%s' "$FILE" | wl-copy
|
||||
notify-send "Path copied" "$FILE"
|
||||
;;
|
||||
"Delete")
|
||||
rm "$FILE"
|
||||
notify-send "Screenshot deleted" "File removed"
|
||||
;;
|
||||
esac
|
||||
|
||||
Reference in New Issue
Block a user