# 機能設計書 23-マウス操作

## 概要

本ドキュメントは、Ghosttyターミナルエミュレータにおける「マウス操作」機能の設計を記述する。マウス操作機能は、ターミナル上でのマウスによるテキスト選択、スクロール、リンククリックなどのインタラクションを提供する機能である。

### 本機能の処理概要

**業務上の目的・背景**：
現代のターミナルユーザーは、キーボードだけでなくマウスによる直感的な操作を期待している。マウス操作機能により、テキストの選択、コピー、スクロール、ハイパーリンクのクリックなど、GUIアプリケーションと同等の操作体験を提供する。これにより、ターミナル初心者から上級者まで、幅広いユーザーの生産性向上に寄与する。

**機能の利用シーン**：
- テキストの選択とクリップボードへのコピー
- スクロールバックバッファのナビゲーション
- URLやファイルパスのクリックによるオープン
- ダブルクリックによる単語選択
- トリプルクリックによる行選択
- 矩形選択（Ctrl+Alt+ドラッグ）

**主要な処理内容**：
1. マウスイベント（クリック、ドラッグ、スクロール）の受信
2. マウス座標からセル座標への変換
3. 選択範囲の計算と管理
4. スクロール処理
5. リンク検出とホバー状態管理
6. マウスカーソル形状の制御

**関連システム・外部連携**：
- レンダラーとの連携（選択範囲の描画）
- クリップボードシステムとの連携
- OS固有のマウスイベントシステム

**権限による制御**：
本機能に特別な権限制御はない。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインターミナルウィンドウ | 主画面 | テキスト選択、スクロール、リンククリック |
| 2 | クイックターミナル | 主画面 | 同上 |
| 3 | スプリットビュー | 主画面 | 各ペインでのマウス操作 |

## 機能種別

イベント処理 / ユーザーインタラクション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| x | f64 | Yes | マウスX座標（ピクセル） | 0以上 |
| y | f64 | Yes | マウスY座標（ピクセル） | 0以上 |
| button | MouseButton | Yes | 押されたボタン | left/middle/right等 |
| state | MouseButtonState | Yes | ボタン状態 | press/release |
| mods | Mods | Yes | 修飾キー状態 | ctrl/shift/alt等 |

### 入力データソース

- OSからのマウスイベント（apprtランタイム経由）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| selection | ?Selection | 現在の選択範囲 |
| mouse_shape | MouseShape | マウスカーソル形状 |
| over_link | bool | リンク上にマウスがあるか |

### 出力先

- ターミナル状態（selection）
- レンダラー（描画更新）
- OS（カーソル形状変更）

## 処理フロー

### 処理シーケンス

```
1. マウスイベント受信
   └─ apprtからのコールバック

2. 座標変換
   └─ ピクセル座標からセル座標への変換

3. イベント種別判定
   ├─ クリック → 選択開始/リンククリック判定
   ├─ ドラッグ → 選択範囲拡張
   ├─ スクロール → スクロールバック移動
   └─ 移動 → リンクホバー判定

4. 状態更新
   └─ 選択範囲、カーソル形状の更新

5. 再描画トリガー
   └─ レンダラーへの更新通知
```

### フローチャート

```mermaid
flowchart TD
    A[マウスイベント受信] --> B{イベント種別}
    B -->|クリック| C{修飾キー}
    B -->|ドラッグ| D[選択範囲拡張]
    B -->|スクロール| E[スクロール処理]
    B -->|移動| F[リンクホバー判定]

    C -->|Shift| G[選択範囲拡張]
    C -->|Ctrl+Alt| H[矩形選択開始]
    C -->|なし| I{ダブル/トリプル?}

    I -->|ダブル| J[単語選択]
    I -->|トリプル| K[行選択]
    I -->|シングル| L[選択開始]

    D --> M[選択状態更新]
    G --> M
    H --> M
    J --> M
    K --> M
    L --> M

    M --> N[再描画トリガー]
    E --> N
    F --> O[カーソル形状更新]
    O --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-23-1 | ダブルクリック単語選択 | 連続クリック間隔内のダブルクリックで単語を選択 | click-repeat-interval内 |
| BR-23-2 | トリプルクリック行選択 | 連続クリック間隔内のトリプルクリックで行を選択 | click-repeat-interval内 |
| BR-23-3 | 矩形選択 | macOSはAlt、他はCtrl+Altで矩形選択モード | ドラッグ開始時 |
| BR-23-4 | マウストラッキングモードオーバーライド | Shiftキーでマウストラッキングをオーバーライド | マウストラッキング有効時 |
| BR-23-5 | コピーオンセレクト | 設定でcopy-on-select有効時、選択完了時に自動コピー | 選択完了時 |

### 計算ロジック

**セル座標変換**:
```
cell_x = floor((mouse_x - padding_left) / cell_width)
cell_y = floor((mouse_y - padding_top) / cell_height)
```

## データベース操作仕様

該当なし（本機能はデータベースを使用しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 座標範囲外 | マウスがターミナル領域外 | イベントを無視 |

### リトライ仕様

該当なし

## トランザクション仕様

該当なし

## パフォーマンス要件

- マウスイベント処理: 60fps以上のレスポンス
- 選択範囲更新: 即時（ドラッグ中もスムーズな更新）

## セキュリティ考慮事項

- クリップボードへの自動コピー（copy-on-select）は機密情報の漏洩リスクがあるため、設定で無効化可能

## 備考

- マウスレポーティング機能（機能No.24）との連携で、TUIアプリケーションへのマウスイベント転送も可能
- マウス非表示機能（mouse-hide-while-typing）との連携

---

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

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

### 推奨読解順序

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

マウス状態管理のデータ構造を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Surface.zig | `src/Surface.zig` | Mouse struct定義（211-256行目） |
| 1-2 | surface_mouse.zig | `src/surface_mouse.zig` | SurfaceMouse struct定義（6-33行目） |

**読解のコツ**: Mouse structの各フィールドが何を追跡しているかを理解する。left_click_pinやclick_stateなどが重要。

#### Step 2: エントリーポイントを理解する

マウスイベントの受信処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | surface_mouse.zig | `src/surface_mouse.zig` | keyToMouseShape関数（53-107行目） |

**主要処理フロー**:
1. **53-56行目**: 適切なキーイベントかのフィルタリング
2. **61-63行目**: リンクホバー/非表示状態の例外処理
3. **66-73行目**: 現在のマウス状態に基づくデフォルト形状決定
4. **81-106行目**: 修飾キーに基づく形状遷移テーブル

#### Step 3: マウス形状制御を理解する

マウスカーソル形状の状態遷移を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | surface_mouse.zig | `src/surface_mouse.zig` | isRectangleSelectState関数（121-126行目） |
| 3-2 | surface_mouse.zig | `src/surface_mouse.zig` | isMouseModeOverrideState関数（115-117行目） |

**主要処理フロー**:
- **115-117行目**: Shiftキーでマウスモードオーバーライド判定
- **121-126行目**: 矩形選択状態の判定（プラットフォーム依存）

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

```
apprt（マウスイベント）
    │
    └─ Surface.mouseButtonCallback() / Surface.mouseMoveCallback()
           │
           ├─ pixelToCell() ────── セル座標変換
           │
           ├─ updateSelection() ─── 選択範囲更新
           │
           ├─ SurfaceMouse.keyToMouseShape()
           │      │
           │      ├─ isMouseModeOverrideState()
           │      │
           │      └─ isRectangleSelectState()
           │
           └─ rt_surface.setMouseShape() ─── カーソル形状設定
```

### データフロー図

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

OSマウスイベント ────▶ Surface.mouse* ────▶ Mouse状態更新
       │                     │
       │                     ▼
       │              pixelToCell() ────▶ セル座標
       │                     │
       │                     ▼
       │              updateSelection() ────▶ Selection
       │                     │
       │                     ▼
       │              keyToMouseShape() ────▶ MouseShape
       │                                          │
       └────────────────────────────────────────▶ rt_surface（描画/カーソル更新）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Surface.zig | `src/Surface.zig` | ソース | Surface状態管理、マウスイベント処理 |
| surface_mouse.zig | `src/surface_mouse.zig` | ソース | マウス状態管理、形状制御ヘルパー |
| Selection.zig | `src/terminal/Selection.zig` | ソース | 選択範囲管理 |
| mouse_shape.zig | `src/terminal/mouse_shape.zig` | ソース | マウス形状定義 |
| action.zig | `src/apprt/action.zig` | ソース | mouse_shapeアクション定義 |
