# 機能設計書 31-フルスクリーン

## 概要

本ドキュメントは、Ghosttyターミナルエミュレータにおけるフルスクリーン機能の設計を定義する。

### 本機能の処理概要

フルスクリーン機能は、ターミナルウィンドウを画面全体に拡大表示し、他のアプリケーションや要素（メニューバー、ドック等）を非表示にすることで、作業に集中できる環境を提供する。

**業務上の目的・背景**：ターミナル作業時に画面全体を使用することで、長いログ出力やコード編集作業において視認性を向上させ、作業効率を高める。特にプレゼンテーションやペアプログラミング時にも有効である。

**機能の利用シーン**：
- 長時間のターミナル作業で集中したい場合
- ログ監視やデバッグ作業で多くの情報を表示したい場合
- プレゼンテーションでターミナル操作をデモする場合
- 画面の小さいノートPCで作業領域を最大化したい場合

**主要な処理内容**：
1. キーバインド（toggle_fullscreen）またはメニューからフルスクリーン切り替えを実行
2. 現在のウィンドウ状態を保存
3. フルスクリーンモード（native/non-native）に応じた画面拡大処理
4. メニューバー、ドック等の非表示化（設定に応じて）
5. フルスクリーン解除時の元状態への復元

**関連システム・外部連携**：
- macOS: AppKit/SwiftUIのフルスクリーンAPI、プレゼンテーションオプション
- Linux/GTK: GTKウィンドウのfullscreen/unfullscreenメソッド

**権限による制御**：特に権限による制御はない。全ユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインターミナルウィンドウ | 主画面 | フルスクリーン表示の切り替え操作 |
| 2 | クイックターミナル | 補助画面 | 非ネイティブフルスクリーン表示 |

## 機能種別

画面制御処理 / ウィンドウ状態管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| mode | Fullscreen (enum) | No | フルスクリーンモード | native, macos_non_native, macos_non_native_visible_menu, macos_non_native_padded_notch |

### 入力データソース

- キーバインド設定（keybind = toggle_fullscreen）
- メニュー操作
- アプリケーションAPI呼び出し

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| isFullscreen | bool | フルスクリーン状態かどうか |

### 出力先

- ウィンドウ状態（フルスクリーン表示）
- 通知センター（fullscreenDidEnter/fullscreenDidExit）

## 処理フロー

### 処理シーケンス

```
1. toggle_fullscreenアクション受信
   └─ キーバインドまたはメニューから呼び出される
2. 現在のフルスクリーン状態を確認
   └─ isFullscreenプロパティをチェック
3. フルスクリーンモードの決定
   └─ 設定値またはパラメータからモードを取得
4. フルスクリーン切り替え処理
   ├─ フルスクリーンでない場合: enter()を呼び出し
   │   ├─ 現在のウィンドウ状態を保存（SavedState）
   │   ├─ ドックを自動非表示に設定
   │   ├─ メニューバーを自動非表示に設定（設定に応じて）
   │   └─ ウィンドウを画面サイズに拡大
   └─ フルスクリーンの場合: exit()を呼び出し
       ├─ 保存した状態を復元
       ├─ ドック・メニューバーを復元
       └─ ウィンドウサイズ・位置を復元
5. デリゲートに状態変更を通知
   └─ fullscreenDidChange()をコール
```

### フローチャート

```mermaid
flowchart TD
    A[toggle_fullscreen受信] --> B{現在フルスクリーン?}
    B -->|No| C{モード判定}
    C -->|native| D[NativeFullscreen.enter]
    C -->|non-native| E[NonNativeFullscreen.enter]
    D --> F[toggleFullScreen呼び出し]
    E --> G[ウィンドウ状態保存]
    G --> H[ドック非表示]
    H --> I[メニュー非表示]
    I --> J[ウィンドウ拡大]
    B -->|Yes| K{現在のモード}
    K -->|native| L[NativeFullscreen.exit]
    K -->|non-native| M[NonNativeFullscreen.exit]
    L --> N[toggleFullScreen呼び出し]
    M --> O[状態復元]
    F --> P[通知送信]
    J --> P
    N --> P
    O --> P
    P --> Q[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-31-01 | ネイティブフルスクリーン | macOSのネイティブフルスクリーンAPIを使用 | mode=native |
| BR-31-02 | 非ネイティブフルスクリーン | タイトルバーを除去しウィンドウを拡大 | mode=macos_non_native |
| BR-31-03 | メニュー表示モード | メニューバーを表示したまま非ネイティブフルスクリーン | mode=macos_non_native_visible_menu |
| BR-31-04 | ノッチパディングモード | ノッチ領域を避けて非ネイティブフルスクリーン | mode=macos_non_native_padded_notch |
| BR-31-05 | クイックターミナル制約 | クイックターミナルは非ネイティブモードのみ | クイックターミナル使用時 |
| BR-31-06 | タブ非サポート | 非ネイティブフルスクリーンはタブをサポートしない | mode=non-native系 |

### 計算ロジック

フルスクリーンフレーム計算（NonNativeFullscreen.fullscreenFrame）:
```
frame = screen.frame
if メニュー表示中:
    frame.height -= メニューバー高さ
else if ノッチパディング有効:
    frame.height -= screen.safeAreaInsets.top
return frame
```

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ウィンドウ取得失敗 | windowがnil | 処理を中断 |
| - | スクリーン取得失敗 | screenがnil | 処理を中断 |
| - | コンテンツビュー取得失敗 | contentViewがnil | SavedState生成失敗 |

### リトライ仕様

リトライは行わない。

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

トランザクションは使用しない。

## パフォーマンス要件

- フルスクリーン切り替えアニメーション: ネイティブ約400ms、非ネイティブは設定可能
- 状態保存・復元: 即座に完了すること

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

特になし。

## 備考

- macOSではネイティブフルスクリーンと非ネイティブフルスクリーンの2種類をサポート
- 非ネイティブフルスクリーンは切り替えが高速だが、タブをサポートしない
- GTK版ではgtk.Window.fullscreen()/unfullscreen()を使用

---

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

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

### 推奨読解順序

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

フルスクリーンに関連するアクションとモードの定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | action.zig | `src/apprt/action.zig` | Fullscreen enumの定義（564-576行目）、toggle_fullscreenアクション |
| 1-2 | Binding.zig | `src/input/Binding.zig` | toggle_fullscreenバインディング定義 |

**読解のコツ**: `Fullscreen` enumは4つのモード（native, macos_non_native, macos_non_native_visible_menu, macos_non_native_padded_notch）を定義している。

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

macOSでのフルスクリーン処理の起点を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Fullscreen.swift | `macos/Sources/Helpers/Fullscreen.swift` | FullscreenMode enum、FullscreenStyleプロトコル |
| 2-2 | TerminalController.swift | `macos/Sources/Features/Terminal/TerminalController.swift` | onToggleFullscreen通知ハンドラ |

**主要処理フロー**:
1. **5-28行目**: FullscreenMode enumの定義と各モードのスタイル生成
2. **31-47行目**: FullscreenStyleプロトコル（enter/exit/isFullscreen等）
3. **90-129行目**: NativeFullscreenクラスのenter/exit実装
4. **131-323行目**: NonNativeFullscreenクラスの実装

#### Step 3: GTK版の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | window.zig | `src/apprt/gtk/class/window.zig` | surfaceToggleFullscreen関数（1630-1642行目） |
| 3-2 | surface.zig | `src/apprt/gtk/class/surface.zig` | toggle-fullscreenシグナルの定義 |

**主要処理フロー**:
- **1630-1642行目**: surfaceToggleFullscreen関数でgtk.Window.fullscreen()/unfullscreen()を呼び出し

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

```
[キーバインド: toggle_fullscreen]
    │
    ├─ [macOS]
    │      ├─ Ghostty.Notification.ghosttyToggleFullscreen
    │      │      └─ TerminalController.onToggleFullscreen
    │      │              └─ BaseTerminalController.toggleFullscreen
    │      │                      └─ FullscreenStyle.enter/exit
    │      │                              ├─ NativeFullscreen (native mode)
    │      │                              └─ NonNativeFullscreen (non-native modes)
    │      │
    │      └─ QuickTerminalController.onToggleFullscreen
    │              └─ NonNativeFullscreen.enter/exit
    │
    └─ [GTK]
           └─ Surface.signals.toggle-fullscreen
                  └─ Window.surfaceToggleFullscreen
                          └─ gtk.Window.fullscreen/unfullscreen
```

### データフロー図

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

キーバインド ─────▶ toggle_fullscreen ─────────────────▶ ウィンドウ状態変更
                    アクション処理
                         │
設定値 ────────────▶ モード判定 ──────▶ Fullscreenスタイル選択
(fullscreen設定)           │
                           │
ウィンドウ状態 ─────▶ 状態保存 ────────▶ SavedState
(フレーム、スタイルマスク等)      │
                                │
                         フルスクリーン ───▶ 画面表示
                         enter/exit         通知送信
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| action.zig | `src/apprt/action.zig` | ソース | Fullscreen enum、toggle_fullscreenアクション定義 |
| Binding.zig | `src/input/Binding.zig` | ソース | キーバインドアクション定義 |
| command.zig | `src/input/command.zig` | ソース | コマンドパレット用コマンド定義 |
| Fullscreen.swift | `macos/Sources/Helpers/Fullscreen.swift` | ソース | macOSフルスクリーン実装 |
| TerminalController.swift | `macos/Sources/Features/Terminal/TerminalController.swift` | ソース | メインターミナルコントローラー |
| QuickTerminalController.swift | `macos/Sources/Features/QuickTerminal/QuickTerminalController.swift` | ソース | クイックターミナルコントローラー |
| window.zig | `src/apprt/gtk/class/window.zig` | ソース | GTKウィンドウ実装 |
| surface.zig | `src/apprt/gtk/class/surface.zig` | ソース | GTKサーフェス実装 |
