# 画面設計書 2-クイックターミナル

## 概要

本ドキュメントは、Ghosttyターミナルエミュレータのクイックターミナル画面の設計について記載する。クイックターミナルは、グローバルホットキーで画面の上下左右からスライドイン/アウトするドロップダウン式のターミナルである。

### 本画面の処理概要

クイックターミナルは、ユーザーがどのアプリケーションを使用中でもホットキー一つで即座にアクセスできるターミナルウィンドウを提供する。

**業務上の目的・背景**：開発者やシステム管理者が、作業中のアプリケーションから離れることなく、素早くコマンドを実行する必要がある場面に対応する。他のアプリケーションの上に表示され、ホットキーで瞬時にトグルできるため、ワークフローの中断を最小限に抑える。

**画面へのアクセス方法**：
- グローバルホットキー（設定可能）でトグル表示
- アプリケーションがアクティブでなくても呼び出し可能

**主要な操作・処理内容**：
1. ホットキーによるウィンドウのスライドイン/スライドアウト
2. コマンドの入力と実行
3. スプリットによるペイン分割（タブは非対応）
4. 非ネイティブフルスクリーンへの切り替え
5. フォーカス喪失時の自動非表示（設定可能）

**画面遷移**：
- ホットキー押下 → クイックターミナル表示/非表示
- スプリット操作 → スプリットビュー（タブは非対応）
- フォーカス喪失時 → 自動的に非表示（autohide設定時）
- メインウィンドウへの変換 → メインターミナルウィンドウ

**権限による表示制御**：特になし。すべてのユーザーが同一の機能を利用可能。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | 端末エミュレーション | 主機能 | ANSIエスケープシーケンスの解釈、端末としての動作を提供 |
| 3 | スクリーン管理 | 主機能 | 端末画面のバッファ管理 |
| 35 | クイックターミナル | 主機能 | グローバルホットキーによるドロップダウン端末のトグル表示 |
| 31 | フルスクリーン | 補助機能 | フルスクリーン表示への切り替え(非ネイティブモード) |
| 29 | スプリット(分割) | 補助機能 | ウィンドウ分割機能(タブは非対応) |
| 39 | 設定ファイル | API連携 | 設定に基づくウィンドウ表示位置、アニメーション、透過設定の適用 |

## 画面種別

ドロップダウン式ターミナル（クイックアクセス）

## URL/ルーティング

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

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 必須 | 説明 |
|--------|----------|----------|------|------|
| コマンド入力 | 入力 | String | - | ユーザーが入力するコマンドテキスト |
| 端末出力 | 出力 | String | - | コマンド実行結果やプログラム出力 |
| 表示位置 | 設定 | QuickTerminalPosition | はい | top/bottom/left/right/center |
| アニメーション時間 | 設定 | Double | - | スライドアニメーションの時間 |
| 自動非表示 | 設定 | Bool | - | フォーカス喪失時の自動非表示 |

## 表示項目

| 項目名 | 表示位置 | データ型 | 説明 |
|--------|----------|----------|------|
| ターミナル表示領域 | 中央 | View | 端末出力を表示するメインエリア |
| スプリットディバイダー | 分割部分 | View | スプリット時の分割線 |

## イベント仕様

### 1-ホットキー押下（トグル）

グローバルホットキーが押下されると、`toggle`メソッドが呼び出され、現在の表示状態に応じて`animateIn`または`animateOut`が実行される。

**処理フロー**：
1. `visible`状態を確認
2. visible=trueの場合: `animateOut`を呼び出し
3. visible=falseの場合: `animateIn`を呼び出し

### 2-アニメーションイン

`animateIn`メソッドが呼び出されると、以下の処理が実行される：

1. visible=trueに設定
2. 前回アクティブだったアプリケーションを記録
3. アクティブなスペースを記録
4. サーフェスツリーが空の場合は新規サーフェスを作成
5. ウィンドウを設定された位置から画面内へアニメーション
6. ウィンドウをキーウィンドウにしてフォーカスを取得

### 3-アニメーションアウト

`animateOut`メソッドが呼び出されると、以下の処理が実行される：

1. visible=falseに設定
2. 前回のアプリケーションがあれば、そのアプリをアクティブに
3. ウィンドウを画面外へアニメーション
4. アニメーション完了後、ウィンドウを非表示に

### 4-フォーカス喪失

ウィンドウがキーウィンドウでなくなった場合（`windowDidResignKey`）：

1. モーダルシートが表示中の場合は何もしない
2. 同じアプリ内の別ウィンドウへの移動の場合はpreviousAppをクリア
3. autoHide設定がtrueの場合は`animateOut`を実行

### 5-スペース移動

`quickTerminalSpaceBehavior`が`.move`の場合、別のスペースに移動するとクイックターミナルも追従する。

### 6-新規タブ試行

クイックターミナルでタブ作成を試行すると、「Tabs aren't supported in the Quick Terminal.」というアラートが表示される。

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

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

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| MSG001 | 警告 | "Cannot Create New Tab" | 新規タブ作成試行時 |
| MSG002 | 情報 | "Tabs aren't supported in the Quick Terminal." | 新規タブ作成試行時 |

## 例外処理

| 例外状況 | 処理内容 |
|----------|----------|
| サーフェスツリーが空 | 新規サーフェスを自動作成 |
| ウィンドウがアクティブスペースにない | アニメーションなしで即座に非表示 |
| 前アプリケーションが終了済み | 復元をスキップ |
| 復元状態が無効 | 新規サーフェスで開始 |

## 備考

- macOS専用機能（GTKには存在しない）
- タブ機能は非対応（スプリットは対応）
- フルスクリーンは非ネイティブモードのみ
- ウィンドウレベルは`.popUpMenu`（アニメーション中）→`.floating`（表示後）
- Dockが競合する位置の場合は自動的にDockを隠す
- 環境変数`GHOSTTY_QUICK_TERMINAL=1`が設定される

---

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

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

### 推奨読解順序

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

まず、クイックターミナル固有の設定とステートを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | QuickTerminalController.swift | `macos/Sources/Features/QuickTerminal/QuickTerminalController.swift` | DerivedConfig構造体（723-751行目）で設定を理解 |
| 1-2 | QuickTerminalPosition | 別ファイル（推定） | 表示位置のenum定義 |

**読解のコツ**: DerivedConfigはGhostty.Configから必要な値を抽出したもの。quickTerminalScreen、quickTerminalAnimationDuration、quickTerminalAutoHide、quickTerminalSpaceBehavior、quickTerminalSizeが重要。

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

QuickTerminalControllerクラスの初期化と基本構造を理解。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | QuickTerminalController.swift | `macos/Sources/Features/QuickTerminal/QuickTerminalController.swift` | クラス定義（7行目）、BaseTerminalControllerを継承 |

**主要処理フロー**:
1. **41-94行目**: init - 初期化、通知の購読
2. **111-151行目**: windowDidLoad - ウィンドウ設定、contentView設定
3. **320-326行目**: toggle - 表示/非表示の切り替え

#### Step 3: アニメーション処理を理解する

表示/非表示のアニメーション処理を理解。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | QuickTerminalController.swift | `macos/Sources/Features/QuickTerminal/QuickTerminalController.swift` | animateIn（328-385行目）、animateOut（387-401行目） |

**主要処理フロー**:
- **419-509行目**: animateWindowIn - ウィンドウを画面内へアニメーション
- **542-598行目**: animateWindowOut - ウィンドウを画面外へアニメーション

#### Step 4: ウィンドウデリゲートを理解する

フォーカス変更時の動作を理解。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | QuickTerminalController.swift | `macos/Sources/Features/QuickTerminal/QuickTerminalController.swift` | windowDidBecomeKey（155-166行目）、windowDidResignKey（168-227行目） |

**主要処理フロー**:
- **168行目**: windowDidResignKey - フォーカス喪失時の処理
- **194-205行目**: autoHide設定に応じた動作分岐

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

```
QuickTerminalController (NSWindowController)
    │
    ├─ extends BaseTerminalController
    │      └─ surfaceTree: SplitTree<Ghostty.SurfaceView>
    │
    ├─ toggle()
    │      ├─ animateIn()
    │      │      └─ animateWindowIn()
    │      └─ animateOut()
    │             └─ animateWindowOut()
    │
    ├─ windowDidResignKey()
    │      └─ (autoHide時) animateOut()
    │
    ├─ windowDidBecomeKey()
    │      └─ hiddenDock?.hide()
    │
    └─ TerminalView (contentView)
           └─ TerminalSplitTreeView
```

### データフロー図

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

ホットキー ─────────────▶ toggle() ─────────────────────▶ visible状態変更
                              │
                              ▼
                        animateIn() / animateOut()
                              │
                              ▼
                        NSAnimationContext
                              │
                              ▼
                        ウィンドウ位置変更

フォーカス喪失 ──────────▶ windowDidResignKey() ────────▶ (autoHide時)
                              │                          animateOut()
                              ▼
                        スペース移動チェック
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| QuickTerminalController.swift | `macos/Sources/Features/QuickTerminal/QuickTerminalController.swift` | ソース | クイックターミナルのメインコントローラー |
| BaseTerminalController.swift | `macos/Sources/Features/Terminal/BaseTerminalController.swift` | ソース | 親クラス、共通機能 |
| TerminalView.swift | `macos/Sources/Features/Terminal/TerminalView.swift` | ソース | ターミナル表示のSwiftUIビュー |
| QuickTerminal.xib | `macos/Resources/QuickTerminal.xib` | リソース | ウィンドウのNib定義 |
| QuickTerminalPosition | （別ファイル） | ソース | 表示位置のenum |
| QuickTerminalSize | （別ファイル） | ソース | サイズ設定 |
| QuickTerminalSpaceBehavior | （別ファイル） | ソース | スペース移動時の動作 |
