# 機能設計書 28-タブ

## 概要

本ドキュメントは、Ghosttyターミナルエミュレータにおける「タブ」機能の設計を記述する。タブ機能は、1つのウィンドウ内で複数のターミナルセッションをタブとして管理し、効率的なセッション切り替えを可能にする機能である。

### 本機能の処理概要

**業務上の目的・背景**：
複数のターミナルセッションを使用する場合、ウィンドウを増やすとデスクトップが煩雑になる。タブ機能により、1つのウィンドウ内で複数のセッションを管理でき、デスクトップスペースを効率的に使用できる。また、関連するタスクをグループ化することで、作業コンテキストの整理が容易になる。

**機能の利用シーン**：
- 同一プロジェクトの複数ターミナル管理
- ビルド、テスト、実行環境の分離
- 複数サーバーへの同時接続
- ログ監視とコマンド実行の並行作業

**主要な処理内容**：
1. 新規タブ作成（new_tab）
2. タブ間移動（previous_tab、next_tab、goto_tab）
3. タブ位置変更（move_tab）
4. タブ概要表示（toggle_tab_overview）
5. タブタイトル変更（prompt_tab_title）
6. タブ閉じる処理（close_tab）

**関連システム・外部連携**：
- ウィンドウ管理システム
- タブバーUI（GTK/macOS）
- スプリット機能（タブ内にスプリットを含む）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインターミナルウィンドウ | 主画面 | タブバーの表示、タブ操作 |
| 8 | タイトル変更ダイアログ | 補助画面 | タブタイトルの編集 |

## 機能種別

UI管理 / セッション管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| tab_index | usize | No | 移動先タブインデックス（goto_tab用） | 1以上 |
| offset | isize | No | タブ移動オフセット（move_tab用） | - |
| mode | CloseTabMode | No | 閉じるモード（close_tab用） | this/other/right |

### 入力データソース

- キーバインドアクション
- タブバーのマウス操作
- メニュー操作

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| active_tab | *Tab | 現在アクティブなタブ |
| tab_count | usize | ウィンドウ内のタブ数 |

### 出力先

- タブバーUI
- ウィンドウタイトル

## 処理フロー

### 処理シーケンス

```
1. タブアクション受信
   └─ new_tab/goto_tab/close_tab等

2. タブ状態更新
   └─ タブリストの更新

3. UI更新
   └─ タブバー、アクティブタブの表示更新

4. フォーカス処理
   └─ 新しいアクティブタブへのフォーカス移動
```

### フローチャート

```mermaid
flowchart TD
    A[タブアクション] --> B{アクション種別}

    B -->|new_tab| C[新規タブ作成]
    B -->|goto_tab| D[タブインデックス検証]
    B -->|previous_tab| E[前のタブに移動]
    B -->|next_tab| F[次のタブに移動]
    B -->|move_tab| G[タブ位置変更]
    B -->|close_tab| H[タブ閉じる処理]

    C --> I[Surface作成]
    I --> J[タブリスト更新]

    D --> K{有効なインデックス?}
    K -->|Yes| L[タブ切り替え]
    K -->|No| M[最後のタブに移動]

    E --> L
    F --> L

    G --> N[タブ順序更新]
    N --> J

    H --> O{閉じるモード}
    O -->|this| P[現在のタブを閉じる]
    O -->|other| Q[他のタブを閉じる]
    O -->|right| R[右のタブを閉じる]

    J --> S[タブバーUI更新]
    L --> S
    P --> S
    Q --> S
    R --> S
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-28-1 | goto_tab範囲 | インデックスがタブ数を超える場合は最後のタブに移動 | goto_tab実行時 |
| BR-28-2 | move_tabラップ | 移動先が範囲外の場合は循環 | move_tab実行時 |
| BR-28-3 | close_tab確認 | confirm-close-surface設定に従って確認ダイアログを表示 | タブ閉じる時 |
| BR-28-4 | last_tab | 最後のタブ（最も右のタブ）に移動 | last_tab実行時 |

### 計算ロジック

**move_tabの循環計算**:
```
new_position = (current_position + offset) % tab_count
if new_position < 0:
    new_position += tab_count
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無効なインデックス | goto_tabに0または負の値 | 最後のタブに移動 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- タブ切り替え: 即時（ミリ秒オーダー）
- タブ作成: 通常1秒以内

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

- 各タブは独立したPTYセッションを持つ
- タブ間でのセキュリティ分離は維持

## 備考

- タブ内にスプリットを含めることが可能
- タブ概要機能（toggle_tab_overview）はlibadwaita 1.4以上で利用可能（Linux）

---

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

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

### 推奨読解順序

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

タブ関連のアクション定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Binding.zig | `src/input/Binding.zig` | タブ関連アクション（534-578行目） |
| 1-2 | Binding.zig | `src/input/Binding.zig` | CloseTabMode enum定義（1135-1141行目） |

**読解のコツ**: new_tab、previous_tab、next_tab、goto_tab、move_tab、close_tabの定義を確認。

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

アクション処理の流れを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | action.zig | `src/apprt/action.zig` | new_tabアクション（89行目） |
| 2-2 | action.zig | `src/apprt/action.zig` | close_tabアクション（93行目） |
| 2-3 | action.zig | `src/apprt/action.zig` | goto_tabアクション（137行目） |
| 2-4 | action.zig | `src/apprt/action.zig` | move_tabアクション（133行目） |

**主要処理フロー**:
1. **89行目**: new_tabはSurfaceをターゲットとしてタブを作成
2. **93行目**: close_tabはモードに応じて閉じるタブを決定
3. **137行目**: goto_tabはタブインデックスを指定

#### Step 3: プラットフォーム実装を理解する

GTKでのタブ実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | tab.zig | `src/apprt/gtk/class/tab.zig` | GTKタブクラス |
| 3-2 | window.zig | `src/apprt/gtk/class/window.zig` | GTKウィンドウでのタブ管理 |

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

```
キーバインド/メニュー
    │
    ├─ new_tab
    │      └─ apprt.createTab()
    │             └─ Surface.init()
    │
    ├─ goto_tab(index)
    │      └─ apprt.switchTab()
    │
    ├─ move_tab(offset)
    │      └─ apprt.moveTab()
    │
    └─ close_tab(mode)
           └─ apprt.closeTab()
```

### データフロー図

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

new_tab ──────────▶ Surface.init() ────────────▶ 新規タブ作成
                          │
                          ▼
                   タブリスト更新 ────────────▶ タブバーUI更新

goto_tab(n) ──────▶ タブインデックス検証 ────▶ アクティブタブ切り替え
                          │
                          ▼
                   フォーカス移動 ────────────▶ 表示更新

close_tab(mode) ──▶ モード判定 ────────────────▶ タブ削除
                          │
                          ├─ this: 現在のタブ
                          ├─ other: 他のタブ
                          └─ right: 右のタブ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Binding.zig | `src/input/Binding.zig` | ソース | タブ関連アクション定義 |
| action.zig | `src/apprt/action.zig` | ソース | apprtタブアクション |
| tab.zig | `src/apprt/gtk/class/tab.zig` | ソース | GTKタブクラス |
| window.zig | `src/apprt/gtk/class/window.zig` | ソース | GTKウィンドウでのタブ管理 |
| Surface.zig | `src/Surface.zig` | ソース | Surface管理 |
