# 通知設計書 9-QuitDialog

## 概要

本ドキュメントは、Windows Terminal におけるアプリケーション終了確認ダイアログ（QuitDialog）の設計仕様を定義する。ユーザーが全ウィンドウの終了（Quit）を要求した際に表示される確認用モーダルダイアログである。

### 本通知の処理概要

QuitDialog は、ユーザーがアプリケーション全体の終了を要求した際に、全ウィンドウを閉じてよいかの確認をモーダルダイアログで行う通知機能である。

**業務上の目的・背景**：Windows Terminal では複数のウィンドウを同時に開くことができ、各ウィンドウには複数のタブが含まれる。アプリケーション全体を終了する `quit` アクションは全ウィンドウを一括で閉じるため、意図しないデータ損失（未保存の作業等）を防ぐための確認が必要である。本ダイアログは操作の最終確認として機能する。

**通知の送信タイミング**：ユーザーが `quit` アクション（キーバインド等）を実行した時に、`_HandleQuit` -> `RequestQuit()` 経由で `_ShowQuitDialog()` が呼び出される。`_displayingCloseDialog` フラグにより、既に別の終了確認ダイアログが表示されている場合は重複表示されない。

**通知の受信者**：終了操作を実行したユーザー自身。モーダルダイアログとして表示される。

**通知内容の概要**：`x:Uid="QuitDialog"` で指定されたローカライズ文字列により、タイトル、本文、ボタンテキストが決定される。DefaultButton は Primary（OK/はい）。

**期待されるアクション**：ユーザーは Primary ボタンで終了を確定するか、Secondary/Close ボタンでキャンセルする。Primary が選択された場合、`QuitRequested` イベントが raise され、アプリケーション全体の終了処理が開始される。

## 通知種別

アプリ内通知（ContentDialog ベースのモーダルダイアログ）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（`co_await` によるダイアログ結果待機） |
| 優先度 | 高（アプリケーション終了確認） |
| リトライ | 無し |

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

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

## 通知テンプレート

### モーダルダイアログ（ContentDialog）の場合

| 項目 | 内容 |
|-----|------|
| UIコントロール | `ContentDialog` |
| 名前 | `QuitDialog` |
| x:Uid | `QuitDialog`（ローカライズキー） |
| DefaultButton | Primary |

### 本文テンプレート

```
Title: {QuitDialog.Title ローカライズ文字列}
Content: {QuitDialog.Content ローカライズ文字列}
PrimaryButton: {QuitDialog.PrimaryButtonText ローカライズ文字列}
SecondaryButton/CloseButton: {QuitDialog.CloseButtonText ローカライズ文字列}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| (x:Uid) | ダイアログのタイトル、本文、ボタンテキスト | QuitDialog ローカライズリソース | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| ユーザーアクション | `quit` アクション | _displayingCloseDialog が false | 全ウィンドウ終了確認ダイアログを表示 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| _displayingCloseDialog が true | 別の終了確認ダイアログが既に表示されている場合、重複表示されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[ユーザーがquitアクション実行] --> B[_HandleQuit]
    B --> C[RequestQuit]
    C --> D{_displayingCloseDialog?}
    D -->|Yes| E[スキップ - 重複表示防止]
    D -->|No| F[_displayingCloseDialog = true]
    F --> G[_ShowQuitDialog]
    G --> H[_ShowDialogHelper L:QuitDialog]
    H --> I[FindName でContentDialog取得]
    I --> J[presenter.ShowDialog]
    J --> K{ユーザー選択}
    K -->|Primary| L[_displayingCloseDialog = false]
    L --> M[QuitRequested.raise]
    K -->|その他| N[_displayingCloseDialog = false]
    N --> O[終了キャンセル]
```

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

### 参照テーブル一覧

該当なし

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 弱参照消失 | co_await 後に TerminalPage が破棄されている場合 | `weak.get()` で null チェック、null なら co_return |
| ダイアログプレゼンター無効 | presenter が取得できない場合 | ダイアログが表示されない |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限 | 同時に1つのみ（_displayingCloseDialog フラグ制御） |

### 配信時間帯

制限なし

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

特になし。終了確認のみのダイアログであり、機密情報は含まれない。

## 備考

- QuitDialog は `_ShowDialogHelper` 共通メソッドを使用して表示される。このメソッドは FindName による遅延ロードと `_dialogPresenter` を経由したダイアログ表示を行う。
- `_displayingCloseDialog` フラグは QuitDialog と CloseAllDialog（No.10）で共有されており、いずれかが表示中は他方も表示されない。
- Primary ボタンが選択された場合のみ `QuitRequested` イベントが raise される。このイベントはアプリケーション全体の終了プロセスを開始する。
- `x:Load="False"` により遅延ロード対象。Grid.Row="2" に配置され、タブコンテンツ領域と同じ行に配置される（GH#12775 のワークアラウンド）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | `_displayingCloseDialog` フラグの宣言を確認 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | `_HandleQuit` メソッド（行126-131）。`RequestQuit()` を呼び出す |

**主要処理フロー**:
1. **行129**: `RequestQuit()` を呼び出す
2. **行130**: `args.Handled(true)` でアクション処理済みとマーク

#### Step 3: ダイアログ表示処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `RequestQuit()` メソッド（行2205-2228）。_displayingCloseDialog チェック、_ShowQuitDialog 呼び出し、結果に応じた QuitRequested イベント |
| 3-2 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `_ShowQuitDialog()` メソッド（行893-896）。_ShowDialogHelper("QuitDialog") を呼び出す |
| 3-3 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `_ShowDialogHelper()` メソッド（行878-884）。FindName と presenter.ShowDialog による共通ダイアログ表示処理 |

**主要処理フロー**:
- **行2207**: `_displayingCloseDialog` チェック
- **行2209**: `_displayingCloseDialog = true` でフラグ設定
- **行2212**: `co_await _ShowQuitDialog()` でダイアログ表示と結果待機
- **行2221**: `ContentDialogResult::Primary` チェック
- **行2226**: Primary の場合 `QuitRequested.raise` でアプリ終了要求

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | TerminalPage.xaml | `src/cascadia/TerminalApp/TerminalPage.xaml` | `QuitDialog` ContentDialog の定義（行89-93）。x:Uid, DefaultButton を確認 |

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

```
ユーザーアクション (quit)
    |
    +-- AppActionHandlers::_HandleQuit (行126)
           |
           +-- TerminalPage::RequestQuit() (行2205)
                  |
                  +-- [_displayingCloseDialog チェック] (行2207)
                  +-- _displayingCloseDialog = true (行2209)
                  +-- _ShowQuitDialog() (行2212)
                  |      |
                  |      +-- _ShowDialogHelper("QuitDialog") (行895)
                  |             |
                  |             +-- FindName("QuitDialog") (行882)
                  |             +-- presenter.ShowDialog() (行882)
                  |
                  +-- [ダイアログ結果待機]
                  +-- _displayingCloseDialog = false (行2219)
                  +-- [Primary の場合] QuitRequested.raise() (行2226)
```

### データフロー図

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

quit アクション       RequestQuit()                       ContentDialog 表示
               --->  _ShowQuitDialog()              --->  (モーダル確認)
                     co_await ダイアログ結果

ユーザー選択          結果判定                             QuitRequested イベント
(Primary/Cancel) --> ContentDialogResult チェック    -->  (Primary時のみ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| TerminalPage.xaml | `src/cascadia/TerminalApp/TerminalPage.xaml` | XAML | QuitDialog のUI定義 |
| TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | ソース | RequestQuit, _ShowQuitDialog, _ShowDialogHelper の実装 |
| TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | ソース | _displayingCloseDialog メンバ宣言 |
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleQuit アクションハンドラ |
