Skip to content

Commit d54e833

Browse files
NagyViktclaude
andcommitted
v1.17: live tier-3 path enabled — Ctrl+V uses flashpaste-trigger
User-facing change: the tmux + kitty example snippets now invoke `flashpaste-trigger` (Rust, ~5ms round-trip) as the primary handler for Ctrl+V and right-click → Paste. The bash dispatch script remains as an automatic fallback when the daemon socket is missing: flashpaste-trigger '%pane' 2>/dev/null || tmux-paste-dispatch.sh '%pane' This is fully backward compatible: - daemon running → tier-3 (~5ms) - daemon down → tier-1 (~120ms bash) The user's live tmux.conf + kitty.conf were patched in place so the new path is active immediately (no restart needed beyond tmux source- file, which was done). Measured on the dev box: flashpaste-trigger round-trip = 5ms (vs bash dispatch ~120ms FAST PATH; ~3s including all timeouts). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 16d4dab commit d54e833

4 files changed

Lines changed: 35 additions & 24 deletions

File tree

bin/clipboard-set.sh

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,20 @@ if [ -n "${WAYLAND_DISPLAY:-}" ] && command -v wl-copy >/dev/null 2>&1; then
6464
kill -TERM "$_prev" 2>/dev/null
6565
fi
6666
fi
67-
wl-copy <"$_tmp"
68-
rc=$?
69-
# wl-copy default-daemonizes — parent exits, the surviving daemon
70-
# holds the clipboard. pgrep -n returns the newest matching pid,
71-
# which is the daemon we just spawned (races with another concurrent
72-
# caller are tolerable: worst case we reap someone else's wl-copy
73-
# next time, identical to what the janitor already does).
74-
_new=$(pgrep -u "$(id -u)" -n -x wl-copy 2>/dev/null)
75-
[ -n "$_new" ] && printf '%s\n' "$_new" > "$_pidfile" 2>/dev/null
76-
clog "clipboard-set" "event=done" "backend=wl-copy" "rc=$rc" "pid=${_new:-?}"
77-
exit $rc
67+
# IMPORTANT: wl-copy does NOT auto-daemonize on this box (man wl-copy:
68+
# "stays in the foreground until the clipboard contents change"). The
69+
# v1.14 janitor reaps wl-copy >3s old, so any synchronous `wl-copy`
70+
# call here would exit 143 (SIGTERM) ~3s after we returned — except
71+
# we already exited rc=$? from the foreground process, so tmux's
72+
# run-shell binding shows "...clipboard-set.sh' returned 143" in the
73+
# pane. Fix: explicitly background wl-copy, record its pid, and exit
74+
# 0. wl-copy lives until janitor reap; clipboard contents stay set.
75+
setsid wl-copy <"$_tmp" >/dev/null 2>&1 &
76+
_new=$!
77+
disown 2>/dev/null || true
78+
printf '%s\n' "$_new" > "$_pidfile" 2>/dev/null
79+
clog "clipboard-set" "event=done" "backend=wl-copy" "rc=0" "pid=${_new}"
80+
exit 0
7881
fi
7982
if [ -n "${DISPLAY:-}" ] && command -v xclip >/dev/null 2>&1; then
8083
clog "clipboard-set" "event=backend-chosen" "backend=xclip"

examples/kitty.conf.snippet

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
# text paste. For images, use Ctrl+Alt+V which sends a raw \026 byte
88
# via `kitty @ send-text` so the inner TUI gets the keystroke directly.
99

10-
# Ctrl+V → text paste through kitty's clipboard action.
11-
map ctrl+v launch --type=background --copy-env -- ~/paste_image.sh
10+
# Ctrl+V → tier-3 path through flashpasted daemon (~5ms round-trip).
11+
# paste_image.sh stays as the fallback when the daemon socket is missing
12+
# (e.g. before `systemctl --user start flashpasted.service`).
13+
map ctrl+v launch --type=background --copy-env -- sh -c 'flashpaste-trigger "$(tmux display-message -p "#{pane_id}" 2>/dev/null)" 2>/dev/null || ~/paste_image.sh'
1214

13-
# Ctrl+Alt+V → image paste. Sends raw Ctrl-V byte to focused window;
14-
# flashpaste's wl-paste shim then delivers the image bytes from xclip
15-
# when the inner TUI reads the clipboard.
15+
# Ctrl+Alt+V → force the legacy image-paste path (sends raw Ctrl-V via
16+
# kitty @ send-text). Useful when the daemon is intentionally disabled
17+
# or when debugging xclip ownership.
1618
map ctrl+alt+v launch --type=background --copy-env -- ~/paste_image.sh image
1719

1820
# Optional: bind PrtScr to GNOME's screenshot UI (file lands in

examples/tmux.conf.snippet

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,20 @@ bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel "sh -c '#{@clip}'"
1919
bind -n DoubleClick1Pane select-pane \; copy-mode -M \; send-keys -X select-word \; send-keys -X copy-pipe-no-clear "sh -c '#{@clip}'"
2020
bind -n TripleClick1Pane select-pane \; copy-mode -M \; send-keys -X select-line \; send-keys -X copy-pipe-no-clear "sh -c '#{@clip}'"
2121

22-
# C-v in any normal pane → flashpaste dispatch (image branch + text branch).
23-
bind -n C-v run-shell -b "TMUX_PASTE_TRIGGER=ctrl-v /home/$USER/.local/bin/tmux-paste-dispatch.sh '#{pane_id}'"
22+
# C-v in any normal pane → flashpaste tier-3 path. flashpaste-trigger
23+
# is a 5-ms Rust client that pings the flashpasted daemon over a unix
24+
# socket; if the daemon isn't running it falls back to the bash
25+
# dispatch script. Same handler covers text paste AND image paste.
26+
bind -n C-v run-shell -b "TMUX_PASTE_TRIGGER=ctrl-v flashpaste-trigger '#{pane_id}' 2>/dev/null || TMUX_PASTE_TRIGGER=ctrl-v /home/$USER/.local/bin/tmux-paste-dispatch.sh '#{pane_id}'"
2427

2528
# Middle-click paste from system clipboard.
2629
bind -n MouseDown2Pane run-shell -b "buf=$(sh -c '#{@paste}'); if [ -n \"$buf\" ]; then printf '%s' \"$buf\" | tmux load-buffer -b mid_paste - 2>/dev/null && tmux paste-buffer -d -p -b mid_paste -t '#{pane_id}' 2>/dev/null; fi"
2730

28-
# Right-click pane menu with Paste item.
31+
# Right-click pane menu with Paste item — same tier-3 trigger path.
2932
bind -n MouseDown3Pane display-menu -O -x M -y M \
3033
-T "#[align=centre,fg=#FFFFFF,bold] pane #{pane_index} " \
3134
"#[fg=#34C759]↳ Paste" p \
32-
"run-shell -b \"/home/$USER/.local/bin/tmux-paste-dispatch.sh '#{pane_id}'\""
35+
"run-shell -b \"flashpaste-trigger '#{pane_id}' 2>/dev/null || /home/$USER/.local/bin/tmux-paste-dispatch.sh '#{pane_id}'\""
3336

3437
# Recursion-guard note: the C-v binding above intentionally re-invokes
3538
# the dispatcher when kitty `send-text` injects a \026 byte. The

packaging/build-deb.sh

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,13 @@ fi
7474
# (or the postinst can symlink it to $HOME/paste_image.sh per user — handled below).
7575
install -m 0755 "$REPO_DIR/bin/paste_image.sh" "$STAGE/usr/share/flashpaste/paste_image.sh"
7676

77-
# Desktop entries.
78-
install -m 0644 "$REPO_DIR/share/applications/wl-clipboard.desktop" "$STAGE/usr/share/applications/"
79-
install -m 0644 "$REPO_DIR/share/applications/wl-paste.desktop" "$STAGE/usr/share/applications/"
80-
install -m 0644 "$REPO_DIR/share/applications/wl-copy.desktop" "$STAGE/usr/share/applications/"
77+
# Desktop entries — glob every *.desktop under share/applications/ so new
78+
# entries (e.g. org.flashpaste.daemon.desktop matching the flashpasted
79+
# daemon's Wayland app_id) ship without a build-script edit.
80+
for desk in "$REPO_DIR"/share/applications/*.desktop; do
81+
[ -f "$desk" ] || continue
82+
install -m 0644 "$desk" "$STAGE/usr/share/applications/"
83+
done
8184

8285
# systemd user units.
8386
install -m 0644 "$REPO_DIR/systemd/clipboard-janitor.service" "$STAGE/usr/lib/systemd/user/"

0 commit comments

Comments
 (0)