# 通知設計書 8-CloseOnExitInfoBar

## 概要

本ドキュメントは、Windows Terminal における終了時動作案内 InfoBar（CloseOnExitInfoBar）の設計仕様を定義する。ターミナル接続が失敗状態になった際に、終了時の動作（close-on-exit）の設定方法を案内する InfoBar 通知である。

### 本通知の処理概要

CloseOnExitInfoBar は、ターミナルのプロセス接続が Failed 状態になった際に、ユーザーに close-on-exit 設定の存在を案内する情報提供型の InfoBar 通知である。

**業務上の目的・背景**：ターミナルのシェルプロセスが終了（Failed 状態）した後もタブが残り続ける場合、ユーザーは「なぜタブが閉じないのか」と疑問を持つことがある。本通知は close-on-exit 設定の存在をユーザーに知らせ、プロファイル設定でターミナル終了時の動作をカスタマイズできることを案内する。

**通知の送信タイミング**：ターミナル接続の状態が `ConnectionState::Failed` に変化した時に、`_ConnectionStateChangedHandler` 内で表示される。UIスレッドへのマーシャリング（`co_await wil::resume_foreground`）の後に実行される。

**通知の受信者**：接続が失敗したターミナルタブを持つウィンドウのユーザー。

**通知内容の概要**：Severity が Informational の InfoBar として、close-on-exit 設定についての案内メッセージ（`x:Uid` で指定されたローカライズ文字列）が表示される。

**期待されるアクション**：ユーザーはメッセージを確認し、必要に応じて settings.json の close-on-exit 設定を変更する。Dismiss ボタンで非表示にでき、一度 Dismiss するとアプリケーション状態に記録されて再表示されない。

## 通知種別

アプリ内通知（InfoBar / 情報バー）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（`co_await wil::resume_foreground` でUIスレッドにマーシャリング） |
| 優先度 | 低（情報提供） |
| リトライ | 無し（一度 Dismiss されると再表示されない） |

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

接続状態が Failed に変化したターミナルコントロールが所属するウィンドウの TerminalPage に表示される。

## 通知テンプレート

### InfoBar の場合

| 項目 | 内容 |
|-----|------|
| UIコントロール | `Microsoft.UI.Xaml.Controls.InfoBar` |
| 名前 | `CloseOnExitInfoBar` |
| x:Uid | `CloseOnExitInfoBar`（ローカライズキー） |
| Severity | Informational |
| IsClosable | True |
| IsIconVisible | True |
| CornerRadius | 0 |

### 本文テンプレート

```
Message: {CloseOnExitInfoBar のローカライズテキスト}
ActionButton: InfoBarDismissButton (x:Uid)
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| (x:Uid) | ローカライズされた案内メッセージ | CloseOnExitInfoBar リソース | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 内部イベント | ConnectionStateChanged | ConnectionState が Failed かつ メッセージが Dismiss 済みでない | 接続失敗時に close-on-exit 設定を案内 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| ConnectionState が Failed 以外 | 接続状態が Failed でない場合は表示されない |
| メッセージが既にDismiss済み | _IsMessageDismissed(InfoBarMessage::CloseOnExitInfo) が true の場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[TermControl: ConnectionStateChanged イベント] --> B[_ConnectionStateChangedHandler]
    B --> C[接続状態を取得]
    C --> D[co_await UIスレッドへマーシャリング]
    D --> E{ConnectionState == Failed?}
    E -->|No| F[表示スキップ]
    E -->|Yes| G{メッセージDismiss済み?}
    G -->|Yes| F
    G -->|No| H[FindName でInfoBar取得]
    H --> I[InfoBar.IsOpen = true]
    I --> J[ユーザーが確認]
    J --> K{Dismissボタン押下?}
    K -->|Yes| L[_CloseOnExitInfoDismissHandler]
    L --> M[_DismissMessage でアプリ状態に記録]
    M --> N[InfoBar.IsOpen = false]
```

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

### 参照テーブル一覧

該当なし

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| ApplicationState（DismissedMessages） | UPDATE | Dismiss 時にメッセージIDを追加 |

#### ApplicationState

| 操作 | 項目 | 更新値 | 備考 |
|-----|------|-------|------|
| UPDATE | DismissedMessages | InfoBarMessage::CloseOnExitInfo を追加 | アプリケーション状態ファイルに永続化 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 弱参照消失 | co_await 後に TerminalPage が破棄されている場合 | `weak.get()` で null チェック、null なら co_return |
| XAML要素未発見 | FindName が null を返す場合 | InfoBar が表示されない（サイレント失敗） |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限 | 特になし（接続失敗ごとに評価されるが、一度 Dismiss すると再表示されない） |

### 配信時間帯

制限なし

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

特になし。表示されるメッセージは設定方法の案内テキストのみ。

## 備考

- `x:Load="False"` が設定されており、必要になるまでXAML要素はロードされない。
- `x:Uid="CloseOnExitInfoBar"` により、Title と Message がローカライズリソースから取得される。
- Dismiss 操作はアプリケーション状態に永続化され、以降のセッションでは再表示されない。
- `_ConnectionStateChangedHandler` は `_RegisterTerminalEvents` で各 TermControl に登録される。
- 同じハンドラ内で `_adjustProcessPriorityThrottled->Run()` も実行される（プロセス優先度の調整）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ApplicationState.idl | `src/cascadia/TerminalSettingsModel/ApplicationState.idl` | `InfoBarMessage` 列挙型で `CloseOnExitInfo` の定義を確認 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `_ConnectionStateChangedHandler()`（行4765-4788）。接続状態の取得、UIスレッドへのマーシャリング、条件チェック、InfoBar 表示 |

**主要処理フロー**:
1. **行4767-4769**: `ICoreState` から `ConnectionState` を取得
2. **行4771**: `co_await wil::resume_foreground` でUIスレッドに切り替え
3. **行4780**: `ConnectionState::Failed` かつ Dismiss 未済をチェック
4. **行4782**: `FindName("CloseOnExitInfoBar")` で InfoBar を遅延ロード
5. **行4784**: `infoBar.IsOpen(true)` で表示

#### Step 3: Dismiss 処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `_CloseOnExitInfoDismissHandler()`（行4797-4804）。_DismissMessage で永続化、InfoBar.IsOpen(false) |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TerminalPage.xaml | `src/cascadia/TerminalApp/TerminalPage.xaml` | `CloseOnExitInfoBar` InfoBar の定義（行44-56）。x:Uid, Severity, ActionButton を確認 |

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

```
TermControl: ConnectionStateChanged イベント
    |
    +-- TerminalPage::_ConnectionStateChangedHandler() (行4765)
           |
           +-- ICoreState.ConnectionState() で状態取得 (行4769)
           +-- co_await UIスレッド (行4771)
           +-- _adjustProcessPriorityThrottled->Run() (行4778)
           +-- [ConnectionState::Failed チェック] (行4780)
           +-- [_IsMessageDismissed チェック] (行4780)
           +-- FindName("CloseOnExitInfoBar") (行4782)
           +-- InfoBar.IsOpen(true) (行4784)

[ユーザーDismiss時]
_CloseOnExitInfoDismissHandler() (行4797)
    |
    +-- _DismissMessage(CloseOnExitInfo) (行4799)
    +-- InfoBar.IsOpen(false) (行4802)
```

### データフロー図

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

ConnectionStateChanged    _ConnectionStateChangedHandler()    InfoBar 表示
(Failed 状態)       --->  条件チェック → FindName       --->  Severity: Informational
                          → IsOpen(true)                      Message: close-on-exit 案内
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TerminalPage.xaml | `src/cascadia/TerminalApp/TerminalPage.xaml` | XAML | CloseOnExitInfoBar のUI定義 |
| TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | ソース | _ConnectionStateChangedHandler と _CloseOnExitInfoDismissHandler |
| ApplicationState.idl | `src/cascadia/TerminalSettingsModel/ApplicationState.idl` | IDL | InfoBarMessage, DismissedMessages の定義 |
