# 通知設計書 54-Attached

## 概要

本ドキュメントは、Windows Terminal における Attached イベント通知の設計仕様を記述する。ControlCore が新しいコントロールにアタッチされた際に発火し、コントロールの初期化完了を通知するアクション通知である。

### 本通知の処理概要

Attached は、ControlCore の AttachToNewControl メソッドが呼び出された際に発火するイベントである。このイベントは、ペインの移動やコンテンツの再接続時に、ControlCore が新しい TermControl にアタッチされたことを通知する。ディスパッチャーやコールバックの再設定が完了し、新しいコントロールがフォントサイズなどの情報を受け取る準備が整ったことを示す。

**業務上の目的・背景**：Windows Terminal ではペインの移動（ウィンドウ間のタブ移動、分割ペインの再配置等）が可能であり、この際に ControlCore インスタンスは保持されたまま新しい TermControl に再接続される。Attached イベントは、この再接続プロセスの完了を通知し、新しいコントロールが適切に初期化されるようにするための仕組みである。

**通知の送信タイミング**：ControlCore::AttachToNewControl() メソッドの実行時、ディスパッチャーとコールバックの再設定（_setupDispatcherAndCallbacks）およびフォントサイズの通知（FontSizeChanged.raise）の後に発火する。

**通知の受信者**：新しい TermControl インスタンスが受信する。受信後、コントロールの初期化処理（レンダラーの再有効化等）を続行する。

**通知内容の概要**：引数なし（nullptr）のシンプルなイベント通知。アタッチが完了したことのみを伝達する。

**期待されるアクション**：受信した TermControl は、必要に応じてレンダラーの再有効化や表示の更新を行い、ユーザーが引き続きターミナルを操作できる状態にする。

## 通知種別

アプリ内イベント通知（WinRT TypedEventHandler）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 高 |
| リトライ | 無 |

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

ControlCore の Attached イベントに登録されたハンドラに通知される。新しい TermControl が AttachToNewControl 呼び出し前にハンドラを登録していることが前提となる。

## 通知テンプレート

### イベント引数

| 項目 | 内容 |
|-----|------|
| イベント型 | `TypedEventHandler<Object, Object>` |
| 定義元 | `ControlCore.idl` L218 |
| プロパティ | なし（sender, nullptr） |

### イベントデータ構造

```cpp
// ControlCore.idl
event Windows.Foundation.TypedEventHandler<Object, Object> Attached;
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| （なし） | イベント引数を持たない | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API呼び出し | ControlCore::AttachToNewControl() | メソッド呼び出し時 | ControlCore.cpp L284-293: ディスパッチャー再設定後にイベント発火 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 特になし | AttachToNewControl が呼び出されれば必ず発火する |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ペイン移動/再接続要求] --> B[ControlCore::AttachToNewControl]
    B --> C[_setupDispatcherAndCallbacks]
    C --> D[フォントサイズ取得]
    D --> E[FontSizeChanged.raise]
    E --> F[Attached.raise]
    F --> G[TermControl: レンダラー再有効化]
    G --> H[Initialize で表示更新]
```

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

### 参照テーブル一覧

該当なし（データベースは使用しない）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ディスパッチャー設定失敗 | UIスレッドの不正状態 | _setupDispatcherAndCallbacks 内で例外処理 |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし

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

- AttachToNewControl の前に Detach が呼ばれ、前のコントロールとの関連が解除されている必要がある
- _setupDispatcherAndCallbacks でスレッドリソースが再設定されるため、スレッド安全性が確保される

## 備考

- Attached イベントの発火前に FontSizeChanged が発火する。これにより、新しいコントロールがフォントサイズ情報を先に受け取ることが保証される
- Attached 発火時点ではレンダラーは無効化されたままである。コメント「The renderer will be re-enabled in Initialize」にあるように、Initialize メソッドで再有効化される
- Detach メソッド（TermControl.idl L168）で前のコントロールからの切り離しが先行する

---

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

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

### 推奨読解順序

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

Attached は引数なしのイベントであるため、IDL定義のみ確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ControlCore.idl | `src/cascadia/TerminalControl/ControlCore.idl` | L218: Attached イベント宣言。他のイベントとは分離して記述されている |

**読解のコツ**: Attached イベントは ControlCore.idl 内で他のイベントとは空行で分離されて記述されており、特別な位置づけであることが示唆されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | L275-294: Detach/AttachToNewControl のペア。Detach でスロットル関数をクリアし、AttachToNewControl で再設定 |

**主要処理フロー**:
1. **L284**: AttachToNewControl メソッド開始
2. **L286**: `_setupDispatcherAndCallbacks()` でディスパッチャーとコールバック再設定
3. **L287**: `_actualFont.GetSize()` で現在のフォントサイズ取得
4. **L289**: `FontSizeChanged.raise()` でフォントサイズを新コントロールに通知
5. **L293**: `Attached.raise(*this, nullptr)` でアタッチ完了を通知

#### Step 3: 前処理（Detach）を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | L275-282: Detach で outputIdle, updateScrollBar のスロットル関数をリセット |

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

```
[ペイン移動/再接続]
    |
    +-- ControlCore::Detach()
    |       +-- shared->outputIdle.reset()
    |       +-- shared->updateScrollBar.reset()
    |
    +-- ControlCore::AttachToNewControl()
            +-- _setupDispatcherAndCallbacks()
            +-- FontSizeChanged.raise()
            +-- Attached.raise(*this, nullptr)
                    |
                    v
            TermControl (新コントロール)
                    +-- レンダラー再有効化
                    +-- Initialize
```

### データフロー図

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

ペイン移動要求 -------> ControlCore::Detach()         TermControl
                              |                       (新コントロール)
                              v                            ^
                        ControlCore                        |
                        ::AttachToNewControl()              |
                              |                            |
                              +-- FontSizeChanged -------->|
                              +-- Attached.raise --------->|
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ControlCore.idl | `src/cascadia/TerminalControl/ControlCore.idl` | IDL定義 | Attached イベント宣言 |
| ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | ソース | AttachToNewControl / Detach 実装 |
| ControlCore.h | `src/cascadia/TerminalControl/ControlCore.h` | ヘッダ | ControlCore クラス宣言 |
| ControlInteractivity.idl | `src/cascadia/TerminalControl/ControlInteractivity.idl` | IDL定義 | Attached 関連の参照 |
| TermControl.idl | `src/cascadia/TerminalControl/TermControl.idl` | IDL定義 | Detach メソッド宣言（L168） |
| TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | ソース | Attached 受信後の処理 |
