# 機能設計書 19-他のペインを閉じる

## 概要

本ドキュメントは、Windows Terminalにおけるフォーカスされたペイン以外のすべてのペインを閉じる機能（CloseOtherPanes アクション）の設計を記述する。

### 本機能の処理概要

現在フォーカスされているペインを残し、同じタブ内の他のすべてのペインを閉じる機能である。読み取り専用ペインは除外される（閉じられない）。ペインは古いものから順番に閉じられ、各ペインの閉じ処理は非同期のコールバックチェーンで実行される。

**業務上の目的・背景**：複数のペインで作業した後、現在の作業ペインだけを残して他のペインを一括で閉じることにより、画面をクリーンアップして集中できる環境を作る。Webブラウザの「他のタブを閉じる」に類似した操作を提供する。

**機能の利用シーン**：分割されたタブ内で多くのペインが開いている状態から、現在作業中のペインだけを残して整理する場面で使用される。

**主要な処理内容**：
1. CloseOtherPanesアクションの受信
2. 対象タブの取得と、アクティブペインの特定
3. ルートペインがアクティブペインと同一でないことを確認
4. ズーム状態の解除
5. WalkTreeで全leafペインを走査し、アクティブペインと読み取り専用ペインを除外
6. 除外されなかったペインのIDリストをソート（昇順）
7. _ClosePanesで順番にペインを閉じる

**関連システム・外部連携**：外部連携なし。

**権限による制御**：読み取り専用ペインは自動的に除外される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleCloseOtherPanesによりフォーカス中以外のペインを閉じる |

## 機能種別

UI操作 / ペイン構造変更

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | CloseOtherPanesアクションにパラメータなし | - |

### 入力データソース

キーバインド、コマンドパレット、またはプログラム的なアクション実行。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ペインツリー更新 | Pane tree | アクティブペインのみが残ったペインツリー |

### 出力先

タブ内のペインツリー

## 処理フロー

### 処理シーケンス

```
1. _HandleCloseOtherPanes が呼び出される
2. _senderOrFocusedTab(sender) で対象タブを取得
3. activeTab->GetActivePane() でアクティブペインを取得
4. activeTab->GetRootPane() != activePane を確認
   └─ ルートとアクティブが同一 → 他にペインがないので何もしない
5. _UnZoomIfNeeded() でズーム解除
6. unfocusedPaneIds リストを構築
   └─ WalkTree でルートペインのleafノードを走査
       └─ 条件: ID あり かつ アクティブペインIDと異なる かつ 読み取り専用でない
7. unfocusedPaneIds をソート（昇順 = 古いペインから）
8. _ClosePanes(activeTab->get_weak(), unfocusedPaneIds) でペインを順番に閉じる
9. args.Handled(true) を設定
```

### フローチャート

```mermaid
flowchart TD
    A[CloseOtherPanes アクション受信] --> B[対象タブ・アクティブペイン取得]
    B --> C{ルート == アクティブ?}
    C -->|Yes| D[Handled = false]
    C -->|No| E[ズーム解除]
    E --> F[WalkTree でleafペインを走査]
    F --> G[アクティブペインと読み取り専用を除外]
    G --> H{閉じるペインあり?}
    H -->|No| D
    H -->|Yes| I[IDリストを昇順ソート]
    I --> J[_ClosePanes で順番に閉じる]
    J --> K[Handled = true]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-19-01 | アクティブペイン保持 | フォーカスされているペインは閉じない | 常時 |
| BR-19-02 | 読み取り専用除外 | 読み取り専用モードのペインは閉じない（ContainsReadOnly チェック） | 常時 |
| BR-19-03 | 単一ペイン時 | ルートペインとアクティブペインが同一（＝他にペインがない）の場合、何もしない | GetRootPane() == activePane |
| BR-19-04 | 閉じ順序 | ペインは ID の昇順（＝古いペインから）で閉じられる | 常時 |
| BR-19-05 | 非同期チェーン | 各ペインの閉じ処理はClosedByParentコールバックチェーンで順番に実行される | 常時 |

### 計算ロジック

特になし。

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

データベース操作なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | タブ未取得 | _senderOrFocusedTab が nullptr を返した場合 | 処理をスキップ |
| なし | 閉じるペインなし | アクティブペイン以外のペインがない、または全て読み取り専用の場合 | Handled(false) を設定 |

### リトライ仕様

リトライ不要。

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

トランザクション管理なし。ペインは1つずつ非同期に閉じられる。

## パフォーマンス要件

複数ペインの閉じ処理は順番に実行されるが、ユーザーにはスムーズに見えること。

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

特になし。

## 備考

- _ClosePanes メソッドは再帰的なコールバックチェーンで実装されている：1つのペインが閉じられるとClosedByParentコールバックが発火し、次のペインの閉じ処理が開始される
- weakThis/weakTabパターンにより、処理中にTabやTerminalPageが破棄された場合のクラッシュを防止
- 各ペインの閉じ処理では _HandleClosePaneRequested が呼ばれるため、復元データも自動的に保存される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | **194-226行目**: _HandleCloseOtherPanes の実装。タブ/ペイン取得、WalkTreeによるID収集、_ClosePanes呼び出し |

**主要処理フロー**:
1. **197行目**: _senderOrFocusedTab で対象タブを取得
2. **199行目**: activeTab->GetActivePane() でアクティブペインを取得
3. **200行目**: ルートペインとアクティブペインの比較
4. **202行目**: _UnZoomIfNeeded() でズーム解除
5. **205-213行目**: WalkTree で全leafペインを走査し、閉じるペインIDを収集
6. **218行目**: IDリストを昇順ソート
7. **219行目**: _ClosePanes で順番にペインを閉じる

**読解のコツ**: WalkTreeはペインツリーの全ノードをDFS（深さ優先探索）で走査するメソッド。ラムダ式で各ノードを処理する。`p->Id()` は leaf ペインのみが持つオプショナル値。

#### Step 2: ペインの順次閉じ処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TabManagement.cpp | `src/cascadia/TerminalApp/TabManagement.cpp` | **801-826行目**: _ClosePanes の実装。再帰的コールバックチェーンによるペインの順次閉じ |

**主要処理フロー**:
- **806-809行目**: IDリストの末尾からペインIDを取り出す
- **811行目**: FindPane(id) で対象ペインを検索
- **813-818行目**: ClosedByParentコールバックを設定（次のペインの_ClosePanesを呼び出す）
- **821行目**: _HandleClosePaneRequested(pane) で実際にペインを閉じる

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

```
TerminalPage::_HandleCloseOtherPanes (AppActionHandlers.cpp:194)
    |
    +-- _senderOrFocusedTab(sender)
    +-- activeTab->GetActivePane()
    +-- activeTab->GetRootPane() との比較
    +-- _UnZoomIfNeeded()
    |
    +-- activeTab->GetRootPane()->WalkTree(lambda)
    |       +-- [各leafペインに対してID収集（アクティブ/ReadOnly除外）]
    |
    +-- std::sort(unfocusedPaneIds)
    |
    +-- _ClosePanes(weakTab, unfocusedPaneIds) (TabManagement.cpp:801)
            |
            +-- FindPane(id) でペイン検索
            |
            +-- pane->ClosedByParent(callback)
            |       +-- callback: _ClosePanes(weakTab, remainingIds)
            |
            +-- _HandleClosePaneRequested(pane) (TabManagement.cpp:749)
                    +-- BuildStartupActions → 復元データ保存
                    +-- pane->Close()
```

### データフロー図

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

CloseOtherPanes       TerminalPage                         ペインツリー
アクション ----------> ::_HandleCloseOtherPanes()  -------> (非アクティブペイン除去)
                           |
                      WalkTree → IDリスト構築
                           |
                      _ClosePanes → 順次閉じ
                           |
                      各ペイン: _HandleClosePaneRequested
                           |
                      復元データ → スタック保存
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleCloseOtherPanes の実装 |
| TabManagement.cpp | `src/cascadia/TerminalApp/TabManagement.cpp` | ソース | _ClosePanes / _HandleClosePaneRequested の実装 |
| TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | ヘッダー | TerminalPage の宣言 |
| Pane.h | `src/cascadia/TerminalApp/Pane.h` | ヘッダー | WalkTree / FindPane / ContainsReadOnly の宣言 |
| Pane.cpp | `src/cascadia/TerminalApp/Pane.cpp` | ソース | Pane のツリー操作メソッドの実装 |
| Tab.cpp | `src/cascadia/TerminalApp/Tab.cpp` | ソース | Tab クラスのペイン操作 |
| Tab.h | `src/cascadia/TerminalApp/Tab.h` | ヘッダー | Tab クラスの宣言 |
