# 機能設計書 12-タブ名変更UIを開く

## 概要

本ドキュメントは、Windows Terminalにおけるタブのインライン名前変更UIを開く機能（OpenTabRenamer アクション）の設計を記述する。

### 本機能の処理概要

タブヘッダー上にインラインのテキスト入力ボックスを表示し、ユーザーが直接タブ名を編集できるようにする機能である。テキストボックスには現在のタブ名が初期値として設定され、Enterキーで確定、Escapeキーでキャンセルが可能である。

**業務上の目的・背景**：No.11「タブ名の変更」機能ではコマンドパレットやキーバインドから固定のタイトルを設定するが、本機能ではユーザーがタブヘッダー上で直接テキストを編集できるGUIを提供する。既存のタブ名を確認しながら編集できるため、より直感的なタブ名変更が可能となる。

**機能の利用シーン**：ユーザーがタブを右クリックしてコンテキストメニューから「名前の変更」を選択する場面、またはキーバインドでタブ名編集モードに入る場面で使用される。タブ名を確認しつつ部分的に修正したい場合に特に有用である。

**主要な処理内容**：
1. OpenTabRenamerアクションの受信
2. 対象タブの特定（sender指定またはフォーカス中のタブ）
3. TabHeaderControlのBeginRenameメソッド呼び出し
4. HeaderTextBlockを非表示にし、HeaderRenamerTextBoxを表示
5. 現在のタブ名をテキストボックスに設定し、全選択状態にする
6. ユーザー入力の受付（Enter確定/Escapeキャンセル/フォーカス喪失時確定）
7. 確定時：TitleChangeRequestedイベントを発火してタブ名を更新

**関連システム・外部連携**：外部連携なし。TabHeaderControl内のXAMLコントロールの表示/非表示を制御する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleOpenTabRenamerによりインライン名前変更UIを開く |
| 3 | TabHeaderControl（タブヘッダー） | 主画面 | HeaderRenamerTextBoxによるインラインタブ名編集 |

## 機能種別

UI操作 / UI表示制御

## 入力仕様

### 入力パラメータ

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

### 入力データソース

キーバインド、コマンドパレット、またはコンテキストメニューからのアクション実行。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| インライン編集UI | XAML TextBox | タブヘッダー内に表示されるテキスト入力ボックス |

### 出力先

TabHeaderControl内のHeaderRenamerTextBox（XAMLコントロール）

## 処理フロー

### 処理シーケンス

```
1. _HandleOpenTabRenamer が呼び出される
   └─ sender から対象タブを特定
2. Tab::ActivateTabRenamer() を呼び出し
   └─ _headerControl.BeginRename() を呼び出し
3. TabHeaderControl::BeginRename() の処理
   ├─ _receivedKeyDown = false, _renameCancelled = false に初期化
   ├─ HeaderTextBlock を非表示に設定
   ├─ HeaderRenamerTextBox を表示に設定
   ├─ 現在のタイトルをテキストボックスに設定
   ├─ テキスト全選択
   └─ テキストボックスにフォーカスを設定
4. ユーザー入力待ち
   ├─ Enter キー → _CloseRenameBox() でUI閉じる
   ├─ Escape キー → _renameCancelled = true, _CloseRenameBox()
   └─ フォーカス喪失 → RenameBoxLostFocusHandler
5. 名前変更の確定
   ├─ キャンセルでない場合 → TitleChangeRequested イベント発火
   └─ キャンセルの場合 → 変更なし
```

### フローチャート

```mermaid
flowchart TD
    A[OpenTabRenamer アクション受信] --> B[対象タブ特定]
    B --> C[ActivateTabRenamer 呼び出し]
    C --> D[BeginRename: テキストボックス表示]
    D --> E{ユーザー操作}
    E -->|Enter| F[_CloseRenameBox]
    E -->|Escape| G[_renameCancelled = true]
    E -->|フォーカス喪失| H[RenameBoxLostFocusHandler]
    G --> F
    H --> I{キャンセル?}
    F --> I
    I -->|No| J[TitleChangeRequested イベント発火]
    I -->|Yes| K[変更なし]
    J --> L[タブ名更新]
    K --> L
    L --> M[RenameEnded イベント発火]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-12-01 | 初期値設定 | テキストボックスには現在のタブタイトルが初期値として設定され、全選択状態になる | BeginRename 呼び出し時 |
| BR-12-02 | Enter確定 | Enterキー押下で名前変更を確定する | テキストボックスがフォーカスを持つ時 |
| BR-12-03 | Escapeキャンセル | Escapeキー押下で名前変更をキャンセルし、元のタブ名を維持する | テキストボックスがフォーカスを持つ時 |
| BR-12-04 | フォーカス喪失時確定 | テキストボックスからフォーカスが外れた場合、キャンセルでなければ変更を確定する | コンテキストメニューが開いている場合は除外 |
| BR-12-05 | ナビゲーションキー抑制 | 上下左右キーはタブ間ナビゲーションに使用されないよう、イベントをHandledとしてマークする | テキストボックスがフォーカスを持つ時 |

### 計算ロジック

特になし。

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

データベース操作なし。UI表示制御のみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | タブ未取得 | _senderOrFocusedTabがnullptrを返した場合 | 処理をスキップ |

### リトライ仕様

リトライ不要。

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

トランザクション管理なし。

## パフォーマンス要件

テキストボックスの表示/非表示の切り替えは即座に行われること。

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

特になし。

## 備考

- GH#9632対応：テキストボックス内でナビゲーションキー（上下左右）が押された場合、タブ間ナビゲーションとして処理されないよう、KeyDownイベントでe.Handled(true)を設定している
- GH#10112対応：InRename()メソッドにより、リネーム中かどうかを外部から判定可能
- テレメトリ送信：BeginRename時に「TabRenamerOpened」、_CloseRenameBox時に「TabRenamerClosed」のテレメトリイベントを送信

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TabHeaderControl.h | `src/cascadia/TerminalApp/TabHeaderControl.h` | **15行目**: BeginRename メソッドの宣言。**22行目**: TitleChangeRequested イベント。**31-32行目**: _receivedKeyDown, _renameCancelled フラグ |

**読解のコツ**: `til::event` はカスタムイベント型。`WINRT_OBSERVABLE_PROPERTY` マクロは変更通知付きプロパティを自動生成する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | **745-753行目**: _HandleOpenTabRenamer。対象タブの ActivateTabRenamer を呼び出す |

**主要処理フロー**:
1. **748行目**: _senderOrFocusedTab(sender) で対象タブを特定
2. **750行目**: activeTab->ActivateTabRenamer() を呼び出し
3. **752行目**: args.Handled(true) を設定

#### Step 3: Tab クラスの中継処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Tab.cpp | `src/cascadia/TerminalApp/Tab.cpp` | **1003-1008行目**: ActivateTabRenamer の実装。_headerControl.BeginRename() を呼び出す |

#### Step 4: TabHeaderControl の UI制御

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TabHeaderControl.cpp | `src/cascadia/TerminalApp/TabHeaderControl.cpp` | **73-91行目**: BeginRename の実装。テキストボックスの表示、初期値設定、フォーカス設定 |
| 4-2 | TabHeaderControl.cpp | `src/cascadia/TerminalApp/TabHeaderControl.cpp` | **21-55行目**: コンストラクタ内のKeyDown/KeyUpイベントハンドラ。Enter/Escape/ナビゲーションキーの処理 |
| 4-3 | TabHeaderControl.cpp | `src/cascadia/TerminalApp/TabHeaderControl.cpp` | **97-125行目**: RenameBoxLostFocusHandler。フォーカス喪失時の処理とTitleChangeRequestedイベント発火 |
| 4-4 | TabHeaderControl.cpp | `src/cascadia/TerminalApp/TabHeaderControl.cpp` | **129-137行目**: _CloseRenameBox。テキストボックス非表示化とRenameEndedイベント発火 |

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

```
TerminalPage::_HandleOpenTabRenamer (AppActionHandlers.cpp:745)
    |
    +-- Tab::ActivateTabRenamer() (Tab.cpp:1003)
            |
            +-- TabHeaderControl::BeginRename() (TabHeaderControl.cpp:73)
                    |
                    +-- HeaderTextBlock.Visibility(Collapsed)
                    +-- HeaderRenamerTextBox.Visibility(Visible)
                    +-- HeaderRenamerTextBox.Text(Title())
                    +-- HeaderRenamerTextBox.SelectAll()
                    +-- HeaderRenamerTextBox.Focus(Programmatic)
                    |
                    +-- [ユーザー操作待ち]
                    |
                    +-- TabHeaderControl::_CloseRenameBox() (TabHeaderControl.cpp:129)
                    |       +-- HeaderRenamerTextBox.Visibility(Collapsed)
                    |       +-- HeaderTextBlock.Visibility(Visible)
                    |       +-- RenameEnded イベント発火
                    |
                    +-- TitleChangeRequested イベント発火 (キャンセルでない場合)
```

### データフロー図

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

アクション           TerminalPage                         TabHeaderControl
(OpenTabRenamer) --> ::_HandleOpenTabRenamer() --------> BeginRename()
                                                           |
                                                     [テキストボックス表示]
                                                           |
                                                     ユーザー入力
                                                           |
                                                     TitleChangeRequested
                                                           |
                                                        Tab::SetTabText()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleOpenTabRenamer の実装 |
| Tab.cpp | `src/cascadia/TerminalApp/Tab.cpp` | ソース | ActivateTabRenamer の実装 |
| Tab.h | `src/cascadia/TerminalApp/Tab.h` | ヘッダー | Tab クラスの宣言 |
| TabHeaderControl.cpp | `src/cascadia/TerminalApp/TabHeaderControl.cpp` | ソース | BeginRename / _CloseRenameBox の実装 |
| TabHeaderControl.h | `src/cascadia/TerminalApp/TabHeaderControl.h` | ヘッダー | TabHeaderControl クラスの宣言 |
| TabHeaderControl.xaml | `src/cascadia/TerminalApp/TabHeaderControl.xaml` | XAML | HeaderTextBlock / HeaderRenamerTextBox のレイアウト定義 |
| TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | ヘッダー | _HandleOpenTabRenamer の宣言 |
