# 通知設計書 43-BackgroundColorChanged

## 概要

本ドキュメントは、Windows Terminal における BackgroundColorChanged イベントの設計仕様を記述する。このイベントは、ターミナルの背景色が変更された際にレンダラーから発火し、UI層に色変更を伝搬する。

### 本通知の処理概要

BackgroundColorChangedイベントは、ターミナルの背景色が変更されたことをUI層に通知するためのイベントである。レンダラー（Renderer）が背景色の変更を検出すると、コールバックを通じてControlCoreの`_rendererBackgroundColorChanged`メソッドが呼び出され、BackgroundColorChangedイベントが発火される。TermControlはこのイベントを受信し、UIスレッド上で背景ブラシの色を更新する。

**業務上の目的・背景**：ターミナルの背景色はVTエスケープシーケンス（OSC 11等）やカラースキームの変更により動的に変わる可能性がある。背景色が変更された場合、XAML UI層のブラシ（AcrylicBrush/SolidColorBrush）を同期的に更新する必要があり、レンダラーからの通知がそのトリガーとなる。

**通知の送信タイミング**：レンダラーが描画フレーム処理中に背景色の変更を検出した際に発火する。具体的には、Renderer::SetBackgroundColorChangedCallbackで設定されたコールバック経由で呼び出される。

**通知の受信者**：TermControlの`_coreBackgroundColorChanged`ハンドラがControlCoreからのイベントを受信する。

**通知内容の概要**：イベント引数は無し（`Object, Object` 型で、sender以外はnullptr）。受信側はControlCore::BackgroundColor()を呼び出して最新の背景色を取得する。

**期待されるアクション**：TermControlはUIスレッドにディスパッチし、`_changeBackgroundColor`メソッドで背景ブラシの色を更新する。AcrylicBrushの場合はTintColorとFallbackColor、SolidColorBrushの場合はColorプロパティを更新する。

## 通知種別

アプリ内通知（WinRT イベント / レンダラーコールバック）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（バックグラウンドスレッドから発火、UIスレッドにディスパッチ） |
| 優先度 | 中 |
| リトライ | 無し |

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

Renderer が背景色変更コールバックを呼び出し、ControlCore が BackgroundColorChanged イベントを発火する。TermControl がwinrt::auto_revokeで購読し、UIスレッドへco_awaitでディスパッチする。

## 通知テンプレート

### メール通知の場合

該当なし（アプリ内イベント通知のため）

### 本文テンプレート

```
該当なし（イベント引数なし。受信側がControlCore::BackgroundColor()で色を取得する）
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| BackgroundColor | 新しい背景色 | ControlCore::BackgroundColor() / Terminal::GetRenderSettings() | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| レンダラーコールバック | 背景色変更検出 | 背景色が変更された時 | Rendererが描画時に背景色変更を検出 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| 特になし | レンダラーが変更を検出した場合は常に発火する |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[VTエスケープシーケンス/カラースキーム変更] --> B[Terminal: 背景色変更]
    B --> C[Renderer: 背景色変更検出]
    C --> D[BackgroundColorChangedCallback呼び出し]
    D --> E[ControlCore::_rendererBackgroundColorChanged]
    E --> F[BackgroundColorChanged.raise]
    F --> G[TermControl::_coreBackgroundColorChanged]
    G --> H[co_await UIスレッドへディスパッチ]
    H --> I[ControlCore::BackgroundColor取得]
    I --> J[_changeBackgroundColor: ブラシ色更新]
```

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

### 参照テーブル一覧

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

### 更新テーブル一覧

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

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| weak_ptr失効 | TermControlがすでに破棄されている場合 | weakThis.get()のnullチェックでスキップ |

### リトライ仕様

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

## 配信設定

### レート制限

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

### 配信時間帯

制限なし

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

背景色情報は純粋なUI設定であり、個人情報や機密情報を含まない。

## 備考

- ControlCore.idlではBackgroundColorChangedは「バックグラウンドスレッドから呼び出される」カテゴリに分類されている
- イベント引数はnullptrであり、受信側がpullモデルで色情報を取得する設計
- Renderer::SetBackgroundColorChangedCallbackはControlCoreのコンストラクタ内（151行目）で設定される
- UseBackgroundImageForWindowが有効な場合、背景色はTransparentに強制される

---

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

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

### 推奨読解順序

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

BackgroundColorChangedは独自のEventArgsを持たない。`Object, Object` 型で、第2引数はnullptrが渡される。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ControlCore.idl | `src/cascadia/TerminalControl/ControlCore.idl` | 195行目: `event ... BackgroundColorChanged` - Object, Object型イベント定義 |
| 1-2 | ControlCore.h | `src/cascadia/TerminalControl/ControlCore.h` | 280行目: `til::typed_event<> BackgroundColorChanged` - 引数なしイベント |

**読解のコツ**: `til::typed_event<>` はテンプレート引数なしの場合、`IInspectable, IInspectable` のペアがデフォルトになる。IDLでは `Object, Object` と表記される。

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

レンダラーのコールバック設定がエントリーポイントとなる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | 151行目: `_renderer->SetBackgroundColorChangedCallback([this]() { _rendererBackgroundColorChanged(); })` |

**主要処理フロー**:
1. **151行目**: ControlCoreコンストラクタ内でRendererにコールバックを登録

#### Step 3: イベント発火処理

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | 1980-1983行目: `_rendererBackgroundColorChanged` 実装 |

**主要処理フロー**:
- **1982行目**: `BackgroundColorChanged.raise(*this, nullptr)` でイベント発火

#### Step 4: レンダラー側のコールバック発火

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | renderer.cpp | `src/renderer/base/renderer.cpp` | 1810行目: SetBackgroundColorChangedCallback定義 |
| 4-2 | renderer.hpp | `src/renderer/base/renderer.hpp` | 72行目: SetBackgroundColorChangedCallback宣言 |

#### Step 5: TermControl側ハンドラ

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | 309行目: `_revokers.BackgroundColorChanged = _core.BackgroundColorChanged(...)` |
| 5-2 | TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | 1128-1138行目: `_coreBackgroundColorChanged` - UIスレッドにディスパッチし_changeBackgroundColor呼び出し |
| 5-3 | TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | 1146-1164行目: `_changeBackgroundColor` - AcrylicBrush/SolidColorBrushの色を更新 |

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

```
Renderer (バックグラウンドスレッド)
    |
    +-- BackgroundColorChangedCallback()
            |
            +-- ControlCore::_rendererBackgroundColorChanged()
                    |
                    +-- BackgroundColorChanged.raise(*this, nullptr)
                            |
                            +-- TermControl::_coreBackgroundColorChanged()
                                    |
                                    +-- co_await wil::resume_foreground(Dispatcher())
                                    |
                                    +-- _core.BackgroundColor() で色取得
                                    |
                                    +-- _changeBackgroundColor(newBgColor)
                                            |
                                            +-- AcrylicBrush.TintColor/FallbackColor 更新
                                            +-- or SolidColorBrush.Color 更新
```

### データフロー図

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

VTエスケープ          Renderer                       TermControl
シーケンス       -->  背景色変更検出                 -->  _changeBackgroundColor()
(OSC 11 等)          BackgroundColorChanged.raise()      AcrylicBrush/SolidColorBrush更新
                     ControlCore::BackgroundColor()       BackgroundBrush プロパティ更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ControlCore.idl | `src/cascadia/TerminalControl/ControlCore.idl` | IDL | BackgroundColorChangedイベント宣言 |
| ControlCore.h | `src/cascadia/TerminalControl/ControlCore.h` | ソース | BackgroundColorChangedイベント定義、_rendererBackgroundColorChanged宣言 |
| ControlCore.cpp | `src/cascadia/TerminalControl/ControlCore.cpp` | ソース | コールバック登録とイベント発火実装 |
| TermControl.cpp | `src/cascadia/TerminalControl/TermControl.cpp` | ソース | _coreBackgroundColorChangedハンドラ、_changeBackgroundColor実装 |
| TermControl.h | `src/cascadia/TerminalControl/TermControl.h` | ソース | ハンドラ宣言 |
| renderer.cpp | `src/renderer/base/renderer.cpp` | ソース | SetBackgroundColorChangedCallback定義 |
| renderer.hpp | `src/renderer/base/renderer.hpp` | ソース | コールバック関数ポインタ宣言 |
| cppwinrt_utils.h | `src/cascadia/inc/cppwinrt_utils.h` | ソース | WinRTユーティリティ |
