You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Phase 2 of the roadmap, completed in one push. The full Rust
workspace under rs/ builds cleanly and ships in the .deb:
flashpasted 2.3 MB persistent daemon (Wayland clipboard
owner + IPC socket + inotify
screenshot watcher all in one process)
flashpaste-dispatch 1.4 MB one-shot Rust replacement for the bash
dispatch script — direct kitty IPC,
in-process X11 selection, no forks
flashpaste-shoot 3.5 MB XDG-portal screenshot tool
flashpaste-trigger 725 KB 1-byte trigger client for the daemon
Build fixes:
- Added nix "user" feature for Uid::current() (was breaking
flashpaste-common::paths::xdg_runtime_dir).
- Workspace builds clean with: cargo build --release.
Packaging:
- packaging/build-deb.sh auto-includes Rust binaries from
rs/target/release/ when present. .deb size: 36 KB (bash-only) →
1.85 MB (full Rust+bash hybrid). Bash tier-1 always present as
fallback.
- .github/workflows/release.yml installs Rust toolchain, caches
~/.cargo + rs/target, builds the workspace, then packages.
Dock-icon fix that actually works:
- share/applications/org.flashpaste.daemon.desktop with
NoDisplay=true + StartupWMClass=org.flashpaste.daemon. The daemon
calls xdg_toplevel.set_app_id("org.flashpaste.daemon"), so GNOME
Shell's app tracker can actually match it to this .desktop and
filter it out — unlike bare wl-paste/wl-copy which had no app_id
and always showed as "Unknown".
Verified:
- flashpasted starts in 7ms, holds 708KB RSS.
- IPC socket at $XDG_RUNTIME_DIR/flashpaste.sock, mode srw-------.
- flashpaste-dispatch / flashpaste-trigger startup: <2ms each.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: README.md
+55-3Lines changed: 55 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,9 +1,17 @@
1
1
# flashpaste
2
2
3
-
> Sub-120ms image-paste into terminal AI agents (Claude Code, Codex, etc.) on GNOME Wayland — even when mutter's clipboard is wedged.
3
+
> Sub-120ms (bash) → sub-40ms (Rust one-shot) → sub-15ms (daemon) image-paste into terminal AI agents (Claude Code, Codex, etc.) on GNOME Wayland — even when mutter's clipboard is wedged.
4
4
5
5
Don't fight the stack. **Install once, paste forever.**`PrtScr` → right-click → **Paste** → the screenshot is attached to your TUI session before you blink. No more retry-spamming Ctrl+V hoping the clipboard daemon will cooperate.
-**Hides the phantom 'wl-clipboard' dock entry via a NoDisplay .desktop file (until the daemon in phase 2 replaces the wl-paste forks entirely).**
27
-
-**End-to-end timing telemetry.** Every step is logged with `T+<ms> Δ<ms>` so regressions are visible at a glance.
34
+
-**No phantom dock icons.** Aggressive janitor + NoDisplay `.desktop` for every short-lived Wayland client.
35
+
-**Three tiers, one knob.** Bash by default; flip a tmux binding to opt into the Rust dispatch or the daemon path.
36
+
-**End-to-end timing telemetry.** Every checkpoint is logged with `T+<ms> Δ<ms>`; `FLASHPASTE_TRACE=1` emits one JSONL row per checkpoint for percentile analysis (`flashpaste-trace.sh`).
28
37
29
38
## Why this exists
30
39
@@ -295,6 +304,49 @@ To revert, point the `bind -n C-v` line back at `tmux-paste-dispatch.sh` — the
295
304
296
305
Same env vars as bash: `FLASHPASTE_QUIET=1` to silence, `FLASHPASTE_TRACE=1` to write the JSON sink to `~/.local/state/flashpaste-trace.jsonl`. Human log is at `~/.local/state/flashpaste-paste.log` by default (override with `FLASHPASTE_LOG`).
297
306
307
+
## Daemon mode (experimental, target <15ms)
308
+
309
+
`flashpasted` (under `rs/flashpasted/`) is a long-lived clipboard owner. It does the slow work — file reads, Wayland/X11 selection claims, kitty socket lookup — **before** the user presses Ctrl-V. The tmux binding then fires a 5-line trigger binary (`flashpaste-trigger`) that writes one JSON message to a unix socket; the daemon already has everything staged and just runs the unbind → kitty send-text → schedule-rebind sequence directly.
310
+
311
+
Bonus side effect: a single persistent Wayland client with a stable `app_id` instead of N short-lived `wl-paste` forks → no more phantom "wl-clipboard" entries in the Ubuntu Dock (cleanly solves what `share/applications/wl-clipboard.desktop` papered over in v1.13).
The trigger is **safe to wire in unconditionally**: if `$XDG_RUNTIME_DIR/flashpaste.sock` doesn't exist (daemon down or not installed), `flashpaste-trigger``exec`s `tmux-paste-dispatch.sh` directly — zero overhead, identical behaviour to Tier 1.
337
+
338
+
### Verify
339
+
340
+
```bash
341
+
systemctl --user status flashpasted # Active (running)
342
+
journalctl --user -u flashpasted -f # Live logs
343
+
ss -lUn | grep flashpaste.sock # Socket present
344
+
```
345
+
346
+
## Fast capture, again
347
+
348
+
When `flashpasted` is running, `flashpaste-shoot` skips the file-on-disk round-trip and stages PNG bytes directly into the daemon's selection owners via the same unix socket. End-to-end Print → ready drops from ~3s (GNOME Screenshot UI) to ~250ms.
0 commit comments