# 機能設計書 62-常に最前面切替

## 概要

本ドキュメントは、Windows Terminalにおける常に最前面切替機能（ToggleAlwaysOnTop）の設計を記述する。

### 本機能の処理概要

ウィンドウの「常に最前面表示」状態を切り替える機能である。有効にすると、ウィンドウが他のアプリケーションウィンドウの上に常に表示される。

**業務上の目的・背景**：サーバーのログ監視やリアルタイムのコマンド実行結果を確認しながら、他のアプリケーションで作業する場合に、ターミナルウィンドウを常に前面に保持する必要がある。この機能により、ターミナルが他のウィンドウの後ろに隠れることを防ぐ。

**機能の利用シーン**：ログ監視、ビルド進捗の確認、バックグラウンドタスクの状態確認など、ターミナルの出力を常に視認しつつ他のアプリケーションを操作する場面で利用される。

**主要な処理内容**：
1. `_HandleToggleAlwaysOnTop`ハンドラがアクションイベントを受け取る
2. `ToggleAlwaysOnTop()`メソッドが`_isAlwaysOnTop`フラグを反転させる
3. `AlwaysOnTopChanged`イベントを発火し、ウィンドウホストに状態変更を通知する
4. ウィンドウホスト（IslandWindow）がWin32 APIを使用してウィンドウのZ-orderを変更する

**関連システム・外部連携**：Win32 API（SetWindowPos等）を使用して、ウィンドウのTOPMOST属性を制御する。設定ファイル（settings.json）のAlwaysOnTopグローバル設定と連動する。

**権限による制御**：特別な権限制御は行わない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleToggleAlwaysOnTopにより常に最前面表示を切替 |

## 機能種別

状態切替操作（トグル）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | トグル動作のため入力パラメータなし | - |

### 入力データソース

キーバインドアクション（ShortcutAction::ToggleAlwaysOnTop）またはコマンドパレットからのアクション呼び出し。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| _isAlwaysOnTop | bool | 常に最前面表示状態フラグ |
| AlwaysOnTopChanged イベント | イベント | ウィンドウホストへの通知 |

### 出力先

ウィンドウのZ-order（TOPMOST属性）に反映される。

## 処理フロー

### 処理シーケンス

```
1. ユーザーがキーバインドまたはコマンドパレットからToggleAlwaysOnTopアクションを実行
   └─ ActionDispatcherがイベントを発火
2. _HandleToggleAlwaysOnTop が呼び出される
   └─ TerminalPage::ToggleAlwaysOnTop() を呼び出す
3. ToggleAlwaysOnTop() が _isAlwaysOnTop を反転
   └─ _isAlwaysOnTop = !_isAlwaysOnTop
4. AlwaysOnTopChanged イベントを発火
   └─ AppHost/IslandWindow がウィンドウのZ-orderを変更
```

### フローチャート

```mermaid
flowchart TD
    A[ToggleAlwaysOnTopアクション受信] --> B[_HandleToggleAlwaysOnTop]
    B --> C[ToggleAlwaysOnTop]
    C --> D[_isAlwaysOnTop = !_isAlwaysOnTop]
    D --> E[AlwaysOnTopChanged.raise]
    E --> F[ウィンドウZ-order変更]
    F --> G[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-62-01 | トグル動作 | 呼び出し毎に_isAlwaysOnTopが反転する | 常に適用 |
| BR-62-02 | 設定反映 | 設定リロード時にsettings.jsonのAlwaysOnTop値が反映される | 設定変更時 |
| BR-62-03 | 複数ウィンドウ | 複数ウィンドウがすべて「常に最前面」の場合、それらの間のZ-orderは独自に維持される | 複数ウィンドウ使用時 |

### 計算ロジック

特別な計算ロジックはない。

## データベース操作仕様

データベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| なし | - | 本機能で直接的なエラー処理は行わない | - |

### リトライ仕様

リトライ処理は不要。

## トランザクション仕様

トランザクション管理は不要。

## パフォーマンス要件

ユーザー操作に対して即座に応答すること。

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

特別なセキュリティ考慮事項はない。

## 備考

- 設定リロード時に`_isAlwaysOnTop`はグローバル設定（`AlwaysOnTop()`）から再読み込みされる（TerminalPage.cpp:3856行目）。ランタイム変更は設定リロードで上書きされる。
- フルスクリーンモードやフォーカスモードと併用可能。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | `_isAlwaysOnTop`フラグ（privateメンバ）、`ToggleAlwaysOnTop()`メソッド宣言（130行目）、`AlwaysOnTopChanged`イベント（188行目）を確認 |

**読解のコツ**: `_isAlwaysOnTop`はTerminalPage.hのprivateセクションに宣言されており、直接外部からアクセスできない。`AlwaysOnTop()`アクセサで読み取る。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | `_HandleToggleAlwaysOnTop`（644-649行目）のハンドラ実装 |

**主要処理フロー**:
1. **644-649行目**: `_HandleToggleAlwaysOnTop` - `ToggleAlwaysOnTop()`を呼び出し、`args.Handled(true)`を設定

#### Step 3: コア処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | `ToggleAlwaysOnTop()`（4074-4078行目）、`AlwaysOnTop()`（4247-4250行目）、設定初期化（438行目）、設定リロード（3856行目）を確認 |

**主要処理フロー**:
- **4074-4078行目**: `ToggleAlwaysOnTop()` - `_isAlwaysOnTop`を反転し、`AlwaysOnTopChanged.raise()`で通知
- **438行目**: 初期化時に`_settings.GlobalSettings().AlwaysOnTop()`から値を取得
- **3856行目**: 設定リロード時に再度設定値を取得

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

```
ActionDispatcher (ShortcutAction::ToggleAlwaysOnTop)
    |
    +-- TerminalPage::_HandleToggleAlwaysOnTop()     [AppActionHandlers.cpp:644]
            |
            +-- TerminalPage::ToggleAlwaysOnTop()    [TerminalPage.cpp:4074]
                    |
                    +-- _isAlwaysOnTop = !_isAlwaysOnTop
                    +-- AlwaysOnTopChanged.raise()
                            |
                            +-- TerminalWindow (イベント中継)
                                    |
                                    +-- AppHost / IslandWindow (Z-order変更)
```

### データフロー図

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

キーバインド/              _HandleToggleAlwaysOnTop()      _isAlwaysOnTop 更新
コマンドパレット -------->  ToggleAlwaysOnTop() ---------->  AlwaysOnTopChanged イベント
                                                           ウィンドウZ-order変更
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | _HandleToggleAlwaysOnTopハンドラ |
| TerminalPage.h | `src/cascadia/TerminalApp/TerminalPage.h` | ヘッダー | ToggleAlwaysOnTop宣言、AlwaysOnTopChangedイベント |
| TerminalPage.cpp | `src/cascadia/TerminalApp/TerminalPage.cpp` | ソース | ToggleAlwaysOnTop実装、初期化・設定リロード処理 |
| TerminalWindow.h | `src/cascadia/TerminalApp/TerminalWindow.h` | ヘッダー | AlwaysOnTopChangedイベントの中継 |
