# 通知設計書 5-WindowRenamer

## 概要

本ドキュメントは、Windows Terminal におけるウィンドウ名変更インタラクティブ通知（WindowRenamer）の設計仕様を定義する。ユーザーが新しいウィンドウ名を入力できる TeachingTip ベースのインタラクティブ通知機能である。

### 本通知の処理概要

WindowRenamer は、ユーザーがウィンドウの名前を変更するためのインタラクティブな入力UIを提供する TeachingTip である。他の Toast 通知とは異なり、自動消去されず、ユーザーが明示的に操作を完了またはキャンセルするまで開き続ける。

**業務上の目的・背景**：Windows Terminal の複数ウィンドウ管理において、各ウィンドウに意味のある名前を付けることで識別性を高める。ユーザーはコマンドパレットやキーバインドからウィンドウ名の変更UIを呼び出し、任意の名前を入力できる。変更されたウィンドウ名は `identifyWindow` 通知やタブバー等で表示される。

**通知の送信タイミング**：ユーザーが `openWindowRenamer` アクション（キーバインド等）を実行した時、またはコマンドパレットから `renameWindow` コマンドを実行した時に表示される。

**通知の受信者**：現在のウィンドウを操作しているユーザー自身。アプリ内UI通知としてウィンドウ上にオーバーレイ表示される。

**通知内容の概要**：Title にウィンドウIDの表示値（`WindowIdForDisplay`）が表示され、Content にテキスト入力ボックス（現在のウィンドウ名が初期値）とアクションボタン（OK）が表示される。

**期待されるアクション**：ユーザーは新しいウィンドウ名を入力し、OKボタンまたは Enter キーで確定する。Escape キーで変更を破棄してダイアログを閉じることもできる。ライトディスミスによる消去も可能。

## 通知種別

アプリ内通知（TeachingTip ベースのインタラクティブ通知）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（UIスレッド上で即時表示） |
| 優先度 | 中 |
| リトライ | 無し |

### 送信先決定ロジック

アクションを実行したウィンドウの TerminalPage 上に直接表示される。

## 通知テンプレート

### アプリ内通知（TeachingTip）の場合

| 項目 | 内容 |
|-----|------|
| UIコントロール | `Microsoft.UI.Xaml.Controls.TeachingTip` |
| 名前 | `WindowRenamer` |
| x:Uid | `WindowRenamer`（ローカライズキー） |
| Title | WindowProperties.WindowIdForDisplay |
| IsLightDismissEnabled | True |
| ActionButtonStyle | AccentButtonStyle |

### 本文テンプレート

```
Title: {WindowProperties.WindowIdForDisplay}
Content: [TextBox: 現在のウィンドウ名]
ActionButton: (x:Uid で指定されたローカライズテキスト)
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| WindowIdForDisplay | ウィンドウIDの表示用文字列 | WindowProperties.WindowIdForDisplay | Yes |
| WindowName | 現在のウィンドウ名（TextBox の初期値） | WindowProperties.WindowName（Mode=OneWay） | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ユーザーアクション | `openWindowRenamer` アクション | 無条件 | ウィンドウ名変更UIを表示 |
| ユーザーアクション | `renameWindow` アクション（引数なし） | 引数のウィンドウ名が空 | コマンドパレット経由でのリネームUI表示 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| TeachingTip の FindName 失敗 | XAML要素が見つからない場合、通知は表示されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ユーザーがopenWindowRenamerアクション実行] --> B[_HandleOpenWindowRenamer]
    B --> C{WindowRenamer == nullptr?}
    C -->|Yes| D[FindName でTeachingTip取得]
    D --> E[Closed コールバック登録]
    C -->|No| F[テーマ更新]
    E --> F
    F --> G[LayoutUpdated イベント登録]
    G --> H[_renamerPressedEnter = false]
    H --> I[WindowRenamer.IsOpen = true]
    I --> J[LayoutUpdated でTextBoxにフォーカス]
    J --> K{ユーザー操作}
    K -->|Enter| L[_WindowRenamerActionClick]
    K -->|OKボタン| L
    K -->|Escape| M[テキスト復元、IsOpen=false]
    L --> N[_RequestWindowRename]
    N --> O[WindowRenamer.IsOpen = false]
    O --> P[RenameWindowRequested イベント発火]
```

### ユーザー操作フロー

```mermaid
flowchart TD
    A[TeachingTip表示] --> B[TextBoxにフォーカス]
    B --> C{ユーザー入力}
    C --> D[新しいウィンドウ名を入力]
    D --> E{確定方法}
    E -->|Enter キー| F[名前変更リクエスト]
    E -->|OKボタン| F
    E -->|Escape キー| G[変更破棄、元の名前に復元]
    E -->|LightDismiss| H[TeachingTip閉じる]
    F --> I[RenameWindowRequested イベント]
    I --> J[Monarch に名前変更を要求]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし

### 更新テーブル一覧

該当なし（ウィンドウ名はメモリ上で管理される）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| XAML要素未発見 | FindName が null を返す場合 | 通知が表示されない |
| 名前変更失敗 | Monarch が名前変更を拒否した場合 | RenameFailed コールバック経由で通知される（別処理） |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限 | 特になし |

### 配信時間帯

制限なし

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

特になし。ウィンドウ名はユーザーが自由に設定できるテキストであり、機密情報は含まれない。

## 備考

- WindowRenamer は他の Toast 通知とは異なり、Toast クラスを使用しない。自動消去タイマーが不要なため、TeachingTip を直接操作する。
- TextBox へのフォーカス設定には BODGY ワークアラウンド（GH#12021）が実装されている。TeachingTip に Opened イベントがない（MUX#1607）ため、LayoutUpdated イベントを利用して2回目のレイアウト更新後にフォーカスを設定する。
- Enter キーの処理では KeyDown と KeyUp の両方を監視し、コマンドパレットから Enter で遷移してきた場合の誤操作を防止する。
- ContentDialog を使わない理由は、Xaml Islands 環境で ContentDialog 内の TextBox がキー入力を受け付けないバグがあるため。
- 名前変更リクエストは非同期で処理される。`RenameWindowRequested` イベントが Monarch に伝搬し、名前の一意性チェック等が行われる。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | `_WindowRenamerActionClick`, `_WindowRenamerKeyDown`, `_WindowRenamerKeyUp` メソッド宣言（行515-518）、`_renamerPressedEnter` と `_renamerLayoutCount` メンバ |

**読解のコツ**: WindowRenamer は Toast クラスを使わず、TeachingTip を直接制御するパターン。Enter キーの KeyDown/KeyUp 二段階検証に注意。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | `_HandleOpenWindowRenamer` メソッド（行1022-1085）。遅延ロード、フォーカス制御のワークアラウンド、IsOpen 設定を確認 |

**主要処理フロー**:
1. **行1025-1031**: WindowRenamer の遅延ロードと Closed コールバック登録
2. **行1034**: テーマ更新
3. **行1060-1078**: LayoutUpdated イベントによるフォーカス制御（BODGY ワークアラウンド）
4. **行1081**: `_renamerPressedEnter = false` で Enter 状態リセット
5. **行1082**: `WindowRenamer().IsOpen(true)` で表示

#### Step 3: ユーザー操作ハンドラを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `_WindowRenamerActionClick`（行4576-4581）: OKボタンクリック時の処理 |
| 3-2 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `_WindowRenamerKeyDown`（行4612-4620）: Enter キー押下追跡 |
| 3-3 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `_WindowRenamerKeyUp`（行4629-4645）: Enter で確定、Escape でキャンセル |
| 3-4 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `_RequestWindowRename`（行4583-4600）: ウィンドウ名変更リクエスト処理 |

**主要処理フロー**:
- **行4579-4580**: テキストボックスの値を取得して `_RequestWindowRename` を呼び出す
- **行4585**: `RenameWindowRequestedArgs` を作成
- **行4590**: WindowRenamer を閉じる
- **行4592**: `RenameWindowRequested` イベントを raise

#### Step 4: XAML定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TerminalPage.xaml | `src/cascadia/TerminalApp/TerminalPage.xaml` | `WindowRenamer` TeachingTip の定義（行189-206）。TextBox の配置、ActionButtonClick イベント、KeyDown/KeyUp イベントを確認 |

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

```
ユーザーアクション (openWindowRenamer)
    |
    +-- AppActionHandlers::_HandleOpenWindowRenamer (行1022)
           |
           +-- FindName("WindowRenamer") ... 初回のみ (行1028)
           +-- _UpdateTeachingTipTheme() (行1034)
           +-- LayoutUpdated イベント登録 (行1061-1078)
           +-- WindowRenamer().IsOpen(true) (行1082)
                  |
                  +-- [ユーザーが名前を入力]
                  |
                  +-- [Enter キー押下]
                  |      +-- _WindowRenamerKeyDown (行4612) ... _renamerPressedEnter = true
                  |      +-- _WindowRenamerKeyUp (行4629) ... _WindowRenamerActionClick 呼び出し
                  |
                  +-- [OK ボタンクリック]
                  |      +-- _WindowRenamerActionClick (行4576)
                  |
                  +-- [Escape キー押下]
                         +-- _WindowRenamerKeyUp (行4638) ... テキスト復元、IsOpen=false

_WindowRenamerActionClick (行4576)
    |
    +-- WindowRenamerTextBox().Text() で新しい名前取得
    +-- _RequestWindowRename(newName) (行4583)
           |
           +-- RenameWindowRequestedArgs 作成 (行4585)
           +-- WindowRenamer().IsOpen(false) (行4590)
           +-- RenameWindowRequested.raise() (行4592)
```

### データフロー図

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

openWindowRenamer       _HandleOpenWindowRenamer            TeachingTip 表示
アクション         ---> TeachingTip.IsOpen(true)      ---> (TextBox + OK ボタン)

ユーザー入力             _WindowRenamerActionClick           RenameWindowRequested
(新しいウィンドウ名) --> _RequestWindowRename           --> イベント → Monarch
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TerminalPage.xaml | `src/cascadia/TerminalApp/TerminalPage.xaml` | XAML | WindowRenamer TeachingTip のUI定義 |
| TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | ソース | _WindowRenamerActionClick/KeyDown/KeyUp/RequestWindowRename の実装 |
| TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | ソース | WindowRenamer 関連メソッドとメンバの宣言 |
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleOpenWindowRenamer アクションハンドラ |
