# 画面設計書 6-クリップボード確認ダイアログ

## 概要

本ドキュメントは、Ghosttyターミナルエミュレータのクリップボード確認ダイアログの設計について記載する。このダイアログは、安全でないペースト操作やOSC52クリップボードアクセス要求時にユーザーに確認を求める。

### 本画面の処理概要

クリップボード確認ダイアログは、潜在的に危険なペースト操作やプログラムからのクリップボードアクセス要求に対して、ユーザーの明示的な許可を得るためのセキュリティ機能を提供する。

**業務上の目的・背景**：ターミナルへのペースト操作は、改行文字を含むコマンドが即座に実行される可能性があり、悪意のあるコードの実行リスクがある。また、OSC52エスケープシーケンスを使用したプログラムからのクリップボードアクセスも、情報漏洩のリスクがある。このダイアログにより、ユーザーが内容を確認してから操作を許可できる。

**画面へのアクセス方法**：
- 危険なコンテンツ（改行を含む、OSC52エスケープを含む等）のペースト時に自動表示
- OSC52によるクリップボード読み取り/書き込み要求時に自動表示

**主要な操作・処理内容**：
1. ペースト/アクセス内容の確認
2. 許可（Paste/Allow）ボタンによる操作の実行
3. 拒否（Cancel/Deny）ボタンによる操作のキャンセル

**画面遷移**：
- ペースト/OSC52要求 → クリップボード確認ダイアログ表示
- 許可/拒否 → ダイアログ閉じる → ターミナル画面

**権限による表示制御**：特になし。すべてのユーザーに同一のダイアログが表示される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 70 | クリップボード操作 | 主機能 | 安全でないペースト操作の確認ダイアログ |
| 78 | 終了確認 | 補助機能 | OSC52クリップボードアクセス要求の確認 |

## 画面種別

確認ダイアログ（モーダルシート）

## URL/ルーティング

N/A（ネイティブデスクトップアプリケーション）

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 必須 | 説明 |
|--------|----------|----------|------|------|
| contents | 入力 | String | はい | ペースト/アクセス対象の内容 |
| request | 入力 | Ghostty.ClipboardRequest | はい | 要求種別（paste/osc_52_read/osc_52_write） |
| delegate | 入力 | ClipboardConfirmationViewDelegate | - | 結果通知用デリゲート |

## 表示項目

| 項目名 | 表示位置 | データ型 | 説明 |
|--------|----------|----------|------|
| 警告アイコン | 左上 | Image | 黄色の三角形警告アイコン |
| 説明テキスト | 右上 | Text | 要求種別に応じた説明 |
| 内容プレビュー | 中央 | TextEditor | ペースト/アクセス内容の表示 |
| キャンセルボタン | 下左 | Button | "Cancel"または"Deny" |
| 確認ボタン | 下右 | Button | "Paste"または"Allow" |

## イベント仕様

### 1-ダイアログ表示

確認が必要なクリップボード操作が発生すると、以下の処理が実行される：

1. `onConfirmClipboardRequest`通知を受信
2. ClipboardConfirmationControllerを作成
3. ウィンドウにモーダルシートとして表示
4. カーソルを表示状態に変更（隠れていた場合）

### 2-許可ボタン押下

「Paste」または「Allow」ボタンが押下されると、以下の処理が実行される：

1. `onPaste()`が呼び出される
2. `delegate.clipboardConfirmationComplete(.confirm, request)`が呼び出される
3. 要求種別に応じた処理が実行される
   - paste: コンテンツをサーフェスに送信
   - osc_52_write: クリップボードに内容を書き込み
   - osc_52_read: クリップボード内容をプログラムに返却

### 3-拒否ボタン押下

「Cancel」または「Deny」ボタンが押下されると、以下の処理が実行される：

1. `onCancel()`が呼び出される
2. `delegate.clipboardConfirmationComplete(.cancel, request)`が呼び出される
3. 操作がキャンセルされる（空文字列が返却される）

### 4-ダイアログ閉じる

ダイアログが閉じられると、以下の処理が実行される：

1. シートが閉じる
2. カーソルが元の状態に戻る（必要な場合は再度非表示）
3. ターミナルにフォーカスが戻る

## データベース更新仕様

N/A（本アプリケーションはデータベースを使用しない）

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | 警告 | request.text() | 要求種別に応じたメッセージ |
| MSG002 | ボタン | "Cancel" / "Deny" | 要求種別による |
| MSG003 | ボタン | "Paste" / "Allow" | 要求種別による |

## 例外処理

| 例外状況 | 処理内容 |
|----------|----------|
| 既にダイアログが表示中 | 新しい要求を即座に完了（空文字列で応答） |
| サーフェスが無効 | 要求をスキップ |
| ウィンドウがない | 即座に成功として処理 |

## 備考

- macOS版はSwiftUIで実装、GTK版はclipboard_confirmation_dialog.zigで実装
- カーソルが非表示の場合は表示状態に変更し、ダイアログ閉じ時に復元
- TextEditorは読み取り専用（focusable: false）
- キーボードショートカット：ESCでキャンセル、Enterで確認

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

要求種別とアクションのenumを理解。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ClipboardConfirmationView.swift | `macos/Sources/Features/ClipboardConfirmation/ClipboardConfirmationView.swift` | Action enum（10-26行目） |
| 1-2 | ClipboardConfirmationViewDelegate | 同上 | プロトコル定義（4-6行目） |

**読解のコツ**: Actionは.cancelと.confirmの2種類。要求種別（paste/osc_52_read/osc_52_write）によってボタンテキストが変わる。

#### Step 2: ビュー構造を理解する

SwiftUIビューの実装を理解。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ClipboardConfirmationView.swift | `macos/Sources/Features/ClipboardConfirmation/ClipboardConfirmationView.swift` | body変数（40-87行目） |

**主要処理フロー**:
1. **42-52行目**: HStackで警告アイコンと説明テキスト
2. **54-56行目**: TextEditorで内容プレビュー
3. **58-66行目**: ボタン配置

#### Step 3: 呼び出し元を理解する

BaseTerminalControllerからの呼び出しを理解。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | BaseTerminalController.swift | `macos/Sources/Features/Terminal/BaseTerminalController.swift` | onConfirmClipboardRequest（1078-1107行目） |
| 3-2 | BaseTerminalController.swift | 同上 | clipboardConfirmationComplete（1109-1137行目） |

### プログラム呼び出し階層図

```
BaseTerminalController
    │
    ├─ onConfirmClipboardRequest (通知受信)
    │      │
    │      └─ ClipboardConfirmationController
    │             │
    │             └─ ClipboardConfirmationView
    │                    ├─ 警告アイコン
    │                    ├─ 説明テキスト
    │                    ├─ TextEditor (内容)
    │                    └─ ボタン (Cancel/Paste)
    │
    └─ clipboardConfirmationComplete (結果処理)
           │
           ├─ osc_52_write → クリップボードに書き込み
           ├─ osc_52_read → 内容を返却
           └─ paste → サーフェスに送信
```

### データフロー図

```
[入力]                     [処理]                         [出力]

クリップボード要求 ───────▶ onConfirmClipboardRequest ──▶ ダイアログ表示
(通知)                         │
                              ▼
                        ClipboardConfirmationView
                              │
                              ▼
ユーザー操作 ───────────────▶ onPaste() / onCancel()
(許可/拒否)                    │
                              ▼
                        clipboardConfirmationComplete
                              │
                              ▼
                        Ghostty.App.completeClipboardRequest
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ClipboardConfirmationView.swift | `macos/Sources/Features/ClipboardConfirmation/ClipboardConfirmationView.swift` | ソース | 確認ダイアログのSwiftUIビュー |
| ClipboardConfirmationController.swift | `macos/Sources/Features/ClipboardConfirmation/ClipboardConfirmationController.swift` | ソース | ウィンドウコントローラー |
| BaseTerminalController.swift | `macos/Sources/Features/Terminal/BaseTerminalController.swift` | ソース | ダイアログの呼び出し元 |
| clipboard_confirmation_dialog.zig | `src/apprt/gtk/class/clipboard_confirmation_dialog.zig` | ソース | GTK版の実装 |
