Skip to content

feat(rust-term,rust-app): OSC 52 クリップボード書き込みに対応(第21波)#158

Merged
sasagar merged 1 commit into
devfrom
feature/osc52-clipboard
Jul 18, 2026
Merged

feat(rust-term,rust-app): OSC 52 クリップボード書き込みに対応(第21波)#158
sasagar merged 1 commit into
devfrom
feature/osc52-clipboard

Conversation

@sasagar

@sasagar sasagar commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • claude はドラッグ選択時に ESC ] 52 ; c ; <base64> BEL/ST(OSC 52)でシステムクリップボードへの書き込みを端末に要求するが、LaboLabo はこれを一切処理していなかった(Ghostty はこれを処理するため素のドラッグでコピーできる)。本 PR で LaboLabo にも同等の対応を追加する。
  • labolabo-term にバックエンド非依存の逐次スキャナ (src/osc52.rs) を追加。セッションのワーカースレッドで PTY 生バイト列を alacritty/ghostty 双方のバックエンドの feed と並行してスキャンし、OSC 52 の set 要求のみを抽出する(TermSession::take_clipboard_set() で一度だけ取り出せる one-shot セマンティクス)。read 要求 (Pd == "?") には一切応答しない(クリップボード内容の漏えい防止)。
  • labolabo-app は既存の redraw bridge(Wakeup 経路)で take_clipboard_set() を確認し、値があれば cx.write_to_clipboard() でシステムクリップボードへ書き込む。

なぜバックエンド非依存のスキャナか

libghostty-vtTerminal は OSC 52 のペイロードを取り出す公開 API を持たない(on_title_changed/on_pty_write/on_device_attributes のみ。低レベルの ghostty_osc_* パーサも CLIPBOARD_CONTENTS のデータ抽出手段を提供しない)。alacritty_terminal は内部で解釈するが EventListener::Event::ClipboardStore 経由のみで、現状どちらのバックエンドもこの経路を配線していない。そのため PTY 生バイト列を直接スキャンする方式とした(詳細は osc52.rs のモジュールコメント)。

テスト

  • osc52.rs 単体テスト 15 件(一括到着/1バイトずつ分割/BEL・ST 両終端/他 OSC との混在/? 読み取り要求の無視/不正 base64/上限超過(1 MiB)/複数シーケンスの順序保証/日本語 UTF-8 ペイロード 等)
  • tests/backend_common.rs に統合テスト 7 件追加(title のテストと同一の idiom)。cargo test -p labolabo-term(alacritty backend)と cargo test -p labolabo-term --no-default-features --features backend-ghostty-vt(ghostty-vt backend、GHOSTTY_SOURCE_DIR 経由)の両方で green。
  • cargo test --workspace / cargo test -p labolabo-app(444 件) / cargo clippy --workspace --all-targets -- -D warnings / cargo fmt --check すべて green。

未検証点

  • 実機 GUI での動作確認は未実施(合成キー入力・合成クリックは使わない方針のため)。クリップボードへの実書き込みは gpui::Context::write_to_clipboard を呼ぶだけのロジックであり、labolabo-term 側の統合テスト(PTY 経由で take_clipboard_set() が期待通り値を返すこと)までで検証を止めている。実際に claude の TUI 上でドラッグ選択してシステムクリップボードに反映されることは、この PR のレビュー/マージ後に実機で確認する必要がある。

Test plan

  • cargo test -p labolabo-term(osc52 単体 15件 + backend_common 統合7件 含む、alacritty backend)
  • cargo test -p labolabo-term --no-default-features --features backend-ghostty-vt
  • cargo test --workspace
  • cargo test -p labolabo-app
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo fmt --check
  • 実機 GUI での claude ドラッグ選択→システムクリップボード反映の確認(未実施、上記「未検証点」参照)

claude はドラッグ選択時に OSC 52 (ESC ] 52 ; c ; <base64> BEL/ST) で
システムクリップボードへの書き込みを端末に要求するが、LaboLabo はこれを
一切処理しておらず、素のドラッグでコピーできなかった(Ghostty はこれを
処理するため可能)。

labolabo-term にバックエンド非依存の逐次スキャナ (osc52.rs) を追加し、
セッションのワーカースレッドで PTY 生バイト列を alacritty/ghostty 双方の
バックエンドと並行してスキャン、OSC 52 の set 要求のみ抽出して
TermSession::take_clipboard_set() で一度だけ取り出せるようにした。
read 要求 (Pd == "?") には一切応答しない(クリップボード漏えい防止)。

labolabo-app 側は既存の redraw bridge (Wakeup 経路) で
take_clipboard_set() を確認し、あれば cx.write_to_clipboard() で
システムクリップボードへ書き込む。
@sasagar
sasagar marked this pull request as ready for review July 18, 2026 13:51
@sasagar
sasagar merged commit a7633a1 into dev Jul 18, 2026
11 checks passed
@sasagar
sasagar deleted the feature/osc52-clipboard branch July 18, 2026 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant