# 機能設計書 22-ペインの移動

## 概要

本ドキュメントは、Windows Terminal における「ペインの移動（MovePane）」機能の設計を記述する。現在フォーカスされているペインを別のタブまたは別のウィンドウに移動する機能である。

### 本機能の処理概要

**業務上の目的・背景**：複数のペインで作業中に、あるペインを別のタブやウィンドウに分離したい場合がある。たとえば、分割表示で始めた作業を独立したタブに昇格させたり、別のウィンドウに移動して画面を広く使いたい場合に本機能が必要となる。

**機能の利用シーン**：ユーザーが複数ペインで作業中に、特定のペインを別タブへ移動して画面を整理する場面や、マルチモニター環境で別ウィンドウにペインを移動する場面で利用される。コマンドラインの`wt move-pane`サブコマンドからも呼び出し可能。

**主要な処理内容**：
1. MovePaneアクション引数からタブインデックスとウィンドウIDを取得する
2. ウィンドウIDが指定されている場合は、ペインを別ウィンドウへ移動する（デタッチ＆再構成）
3. タブインデックスが指定されている場合は、同一ウィンドウ内の別タブへペインを移動する
4. タブインデックスが既存タブ数を超える場合は、新しいタブを作成してペインを配置する
5. 移動元タブの最後のペインであった場合はタブが自動的に閉じられる

**関連システム・外部連携**：別ウィンドウへの移動時は、ウィンドウ間通信（`_MoveContent`）を使用して起動アクションを転送する。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleMovePaneによりペイン移動を処理 |

## 機能種別

UI操作（ペイン管理・タブ間移動）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| TabIndex | UInt32 | No | 移動先のタブインデックス（0始まり） | 現在のタブと同一でないこと |
| Window | String | No | 移動先のウィンドウID/名前 | 空でない場合は別ウィンドウ移動 |

### 入力データソース

キーバインド設定またはコマンドライン（`wt move-pane`サブコマンド）。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Handled | bool | ペイン移動が成功したかどうか |

### 出力先

UI更新（ペインのタブ間移動またはウィンドウ間移動）。アクセシビリティ通知。

## 処理フロー

### 処理シーケンス

```
1. _HandleMovePane が ActionEventArgs を受信
   └─ MovePaneArgs にキャストして TabIndex/Window を取得
2. _MovePane(realArgs) を呼び出し
3. Window が指定されている場合（別ウィンドウ移動）
   └─ ペインの起動アクションを構築 (BuildStartupActions)
   └─ _DetachPaneFromWindow でペインをデタッチ
   └─ _MoveContent でアクションを別ウィンドウに転送
   └─ focusedTab->DetachPane() でタブからペインを切り離し
4. Window が空で TabIndex が指定されている場合（同一ウィンドウ内移動）
   └─ 現在のタブと同じインデックスの場合はスキップ
   └─ TabIndex < タブ数: 既存タブにペインをアタッチ
   └─ TabIndex >= タブ数: 新しいタブを作成してペインを配置
5. アクセシビリティ通知を発行
```

### フローチャート

```mermaid
flowchart TD
    A[MovePane アクション発火] --> B{Window が空?}
    B -->|No| C[別ウィンドウ移動]
    C --> D[BuildStartupActions]
    D --> E[_DetachPaneFromWindow]
    E --> F[_MoveContent で転送]
    F --> G[DetachPane]
    B -->|Yes| H{現在のタブと同じ?}
    H -->|Yes| I[false を返す]
    H -->|No| J{TabIndex < タブ数?}
    J -->|Yes| K[既存タブにアタッチ]
    J -->|No| L[新規タブ作成してアタッチ]
    K --> M[アクセシビリティ通知]
    L --> M
    G --> M
    M --> N[true を返す]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-22-01 | 同一タブ移動の防止 | 現在のタブと同じインデックスへの移動は無操作 | Window未指定かつTabIndexが現在タブ |
| BR-22-02 | 新規タブ自動作成 | TabIndexが既存タブ数を超える場合は新しいタブを自動作成 | TabIndex >= タブ数 |
| BR-22-03 | 非ターミナルタブへの移動不可 | 設定タブなどターミナルをホストしないタブへの移動は失敗する | 移動先が非ターミナルタブ |
| BR-22-04 | 別ウィンドウ移動時のデタッチ | 別ウィンドウ移動時はペインのコネクション管理からもデタッチする | Window指定時 |

### 計算ロジック

特になし。

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

### 操作別データベース影響一覧

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無操作 | フォーカスされたタブが存在しない | false を返す |
| - | 無操作 | 同一タブへの移動指定 | false を返す |
| - | 移動失敗 | 移動先タブが非ターミナルタブ | false を返す |

### リトライ仕様

リトライは不要。

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

ペインの移動は「デタッチ→アタッチ」の2段階で行われる。途中で失敗した場合のロールバック機構は明示されていない。

## パフォーマンス要件

即座に完了する処理。別ウィンドウ移動の場合はウィンドウ間通信のオーバーヘッドがある。

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

特になし。

## 備考

- `wt move-pane` コマンドラインサブコマンドからも呼び出し可能（AppCommandlineArgs.cpp）。
- Window に "new" を指定すると新しいウィンドウが作成される。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | **220-225行目**: MovePaneArgs クラスの定義。TabIndex (UInt32) と Window (String) プロパティを持つ |

**読解のコツ**: MovePaneArgs はタブインデックスとウィンドウIDの2つのパラメータを持ち、Windowが指定された場合は別ウィンドウ移動が優先される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | **228-240行目**: `_HandleMovePane` メソッド。MovePaneArgs にキャストし _MovePane を呼び出す |

**主要処理フロー**:
1. **235行目**: `args.ActionArgs().try_as<MovePaneArgs>()` でアクション引数を取得
2. **237行目**: `_MovePane(realArgs)` を呼び出す
3. **238行目**: 結果を `args.Handled()` に設定

#### Step 3: _MovePane の実装

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | **2393-2484行目**: `_MovePane` メソッドの全体。Window指定時と TabIndex 指定時の分岐処理 |

**主要処理フロー**:
- **2395-2396行目**: TabIndex と Window の取得
- **2407行目**: Window が空でない場合の別ウィンドウ移動処理
- **2413行目**: `BuildStartupActions` でペインの起動アクションを構築
- **2414行目**: `_DetachPaneFromWindow` でコネクション管理からデタッチ
- **2415行目**: `_MoveContent` で別ウィンドウに起動アクションを転送
- **2441行目**: 同一タブへの移動チェック
- **2448-2458行目**: 既存タブへの移動（DetachPane + AttachPane）
- **2472-2473行目**: 新規タブの作成（DetachPane + _CreateNewTabFromPane）

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

```
TerminalPage::_HandleMovePane (AppActionHandlers.cpp:228)
    |
    +-- TerminalPage::_MovePane (TerminalPage.cpp:2393)
            |
            +-- [Window指定時]
            |       +-- Pane::BuildStartupActions
            |       +-- TerminalPage::_DetachPaneFromWindow
            |       +-- TerminalPage::_MoveContent
            |       +-- Tab::DetachPane
            |
            +-- [同一ウィンドウ内]
                    +-- Tab::DetachPane (移動元)
                    +-- Tab::AttachPane (移動先) / _CreateNewTabFromPane (新規タブ)
```

### データフロー図

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

MovePaneArgs ──> TabIndex + Window ──> _MovePane
                                           |
                      [Window 指定時]       |       [TabIndex 指定時]
                            |               |              |
               BuildStartupActions   ─── 分岐 ───  DetachPane
                            |                              |
               _DetachPaneFromWindow               AttachPane / _CreateNewTabFromPane
                            |                              |
                    _MoveContent ──> 別ウィンドウ    移動先タブ / 新規タブ
                                                           |
                                                   アクセシビリティ通知
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleMovePane アクションハンドラ |
| TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | ソース | _MovePane メソッドの実装 |
| Tab.cpp | `src/cascadia/TerminalApp/Tab.cpp` | ソース | DetachPane / AttachPane メソッド |
| Pane.cpp | `src/cascadia/TerminalApp/Pane.cpp` | ソース | BuildStartupActions メソッド |
| TerminalPaneContent.cpp | `src/cascadia/TerminalApp/TerminalPaneContent.cpp` | ソース | ペインコンテンツの管理 |
| ActionArgs.idl | `src/cascadia/TerminalSettingsModel/ActionArgs.idl` | IDL | MovePaneArgs の型定義 |
| ActionArgs.cpp | `src/cascadia/TerminalSettingsModel/ActionArgs.cpp` | ソース | MovePaneArgs::GenerateName の実装 |
| AppCommandlineArgs.cpp | `src/cascadia/TerminalApp/AppCommandlineArgs.cpp` | ソース | move-pane コマンドラインサブコマンドの解析 |
