# 機能設計書 71-Quakeモード

## 概要

本ドキュメントは、Windows TerminalにおけるQuakeモード機能の設計を記述する。Quakeモードは画面上部からスライドダウンするスタイルのウィンドウ表示を実現する機能である。

### 本機能の処理概要

Quakeモードは、FPSゲーム「Quake」のコンソール表示を模した、画面上部半分にドロップダウンするターミナルウィンドウ表示機能である。ユーザーはグローバルホットキーまたはコマンドから素早くターミナルにアクセスできる。

**業務上の目的・背景**：開発者やシステム管理者が、任意のアプリケーション作業中に素早くターミナルにアクセスしたいという要求に応える。画面上部にオーバーレイとして表示されるため、通常のウィンドウ管理を中断せずにコマンド実行が可能となる。ゲーマー向けターミナルエミュレータで広く採用されたUIパターンを取り入れている。

**機能の利用シーン**：開発中にブラウザやエディタから離れずにターミナルコマンドを実行したい場合、素早いコマンド実行が必要な場面、デモンストレーション時にフルスクリーンアプリケーション上にターミナルをオーバーレイ表示したい場合などに利用される。

**主要な処理内容**：
1. QuakeModeアクションの受信とウィンドウのQuakeモード状態への遷移
2. 現在のモニター情報の取得とウィンドウサイズ・位置の計算
3. ウィンドウの画面上部半分へのリサイズと配置
4. ウィンドウ移動・リサイズの制限（下辺のみリサイズ可能）
5. モニター間移動時のサイズ再調整

**関連システム・外部連携**：Windows OS のウィンドウ管理API（Win32 API）、マルチモニター環境のモニター情報取得API（MonitorFromRect、GetMonitorInfo）と連携する。

**権限による制御**：特になし。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | TerminalPage（メイン画面） | 主画面 | _HandleQuakeModeによりQuakeスタイルのウィンドウ表示 |

## 機能種別

UI制御 / ウィンドウ管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | QuakeModeアクションにはパラメータなし | - |

### 入力データソース

キーバインドまたはコマンドパレットからのアクション発行。グローバルホットキーからの呼び出し。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ウィンドウ位置 | RECT | モニター上部半分に配置されたウィンドウ矩形 |
| _isQuakeWindow | bool | Quakeモード状態フラグ |

### 出力先

ウィンドウのサイズ・位置変更（Win32 SetWindowPos API経由）

## 処理フロー

### 処理シーケンス

```
1. QuakeModeアクション受信
   └─ _HandleQuakeModeハンドラが呼び出される（TerminalPage）
2. TerminalWindow への通知
   └─ TerminalWindow::_HandleQuakeModeで IsQuakeWindow プロパティを設定
3. IslandWindow::IsQuakeWindow(true) の呼び出し
   └─ _isQuakeWindowフラグをtrueに設定
4. _enterQuakeMode() の実行
   └─ 現在のウィンドウ矩形からモニターを特定
5. _getQuakeModeSize() によるサイズ計算
   └─ モニターの作業領域の上半分のサイズを算出
6. SetWindowPos による位置・サイズ設定
   └─ SWP_SHOWWINDOW | SWP_FRAMECHANGED フラグで配置
```

### フローチャート

```mermaid
flowchart TD
    A[QuakeModeアクション受信] --> B[_HandleQuakeMode]
    B --> C{HWNDが存在するか}
    C -->|Yes| D[_isQuakeWindow = true]
    C -->|No| E[フラグのみ設定して終了]
    D --> F[_enterQuakeMode]
    F --> G[MonitorFromRectでモニター特定]
    G --> H[_getQuakeModeSize でサイズ計算]
    H --> I[モニター作業領域の取得]
    I --> J[DPI考慮した非クライアント領域計算]
    J --> K[上半分のサイズ算出]
    K --> L[SetWindowPos で配置]
    L --> M[終了]
    E --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-71-01 | リサイズ制限 | Quakeウィンドウは下辺のみリサイズ可能 | IsQuakeWindow() == true の場合、_OnSizing で下辺以外のリサイズを拒否 |
| BR-71-02 | 移動制限 | Quakeウィンドウは手動移動不可 | IsQuakeWindow() == true の場合、_OnMoving で移動を拒否 |
| BR-71-03 | モニター追従 | モニター間移動時にサイズを再計算 | WM_WINDOWPOSCHANGING でモニター変更を検出した場合 |
| BR-71-04 | 境界調整 | 隣接モニターにはみ出さないよう1px縮小 | _getQuakeModeSize でncSize考慮後に左右1pxずつ縮小 |

### 計算ロジック

Quakeモードのウィンドウサイズ計算:
- 原点X = モニター作業領域左端 - (非クライアント領域幅 / 2) + 1
- 原点Y = モニター作業領域上端
- 幅 = 作業領域幅 + 非クライアント領域幅 - 2
- 高さ = (作業領域高さ + 非クライアント領域高さ) / 2

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

### 操作別データベース影響一覧

本機能にデータベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ウィンドウ未作成 | _window が null の場合 | _enterQuakeMode を早期リターン |
| - | グローバルホットキー登録失敗 | ホットキーが他アプリに占有されている場合 | args.Handled(false) を設定し、キー入力を通常処理に委任 |

### リトライ仕様

リトライは不要。

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

本機能にトランザクション処理はない。

## パフォーマンス要件

ウィンドウのリサイズ・再配置は即座に完了すること。アニメーション付きのドロップダウン表示は _doSlideAnimation で制御される。

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

グローバルホットキーの登録は OS レベルで管理される。特別なセキュリティ考慮事項はない。

## 備考

- Quakeモードは主にコマンドラインオプション `--window _quake` で起動される
- グローバル呼び出し（GlobalSummon）機能と連携して動作する
- 自動非表示（autoHideWindow）設定と組み合わせて使用されることが多い

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IslandWindow.h | `src/cascadia/WindowsTerminal/IslandWindow.h` | _isQuakeWindowフラグ（144行目）、_autoHideWindowフラグ（145行目）、_enterQuakeMode/IsQuakeWindowメソッド宣言 |
| 1-2 | AllShortcutActions.h | `src/cascadia/TerminalSettingsModel/AllShortcutActions.h` | QuakeModeアクションの定義 |

**読解のコツ**: IslandWindowはWin32ウィンドウをラップするC++クラスである。BaseWindowテンプレートクラスを継承しており、HWNDの管理とメッセージ処理を担当する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | _HandleQuakeModeハンドラ（1156-1165行目）。グローバルホットキー登録失敗時にargs.Handled(false)を返す |

**主要処理フロー**:
1. **1156-1157行目**: _HandleQuakeModeハンドラの定義
2. **1163行目**: args.Handled(false) - この関数は本来TerminalPage経由で呼ばれるべきではなく、グローバルホットキー失敗時のフォールバック

#### Step 3: ウィンドウ管理層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | IslandWindow.cpp | `src/cascadia/WindowsTerminal/IslandWindow.cpp` | IsQuakeWindow setter（1631-1641行目）、_enterQuakeMode（1656-1676行目）、_getQuakeModeSize（1686-1717行目） |

**主要処理フロー**:
- **1626-1629行目**: IsQuakeWindow() getter - _isQuakeWindowの返却
- **1631-1641行目**: IsQuakeWindow(bool) setter - フラグ変更時に_enterQuakeMode呼び出し
- **1656-1676行目**: _enterQuakeMode() - モニター特定とSetWindowPos呼び出し
- **1686-1717行目**: _getQuakeModeSize() - モニター情報からウィンドウサイズを計算
- **256-264行目**: _OnSizing() - Quakeウィンドウのリサイズ制限（下辺のみ許可）
- **352-364行目**: _OnMoving() - Quakeウィンドウの移動制限
- **644-654行目**: WM_WINDOWPOSCHANGING - モニター間移動時のサイズ再調整

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

```
TerminalPage::_HandleQuakeMode (AppActionHandlers.cpp:1156)
    │
    └─ (イベント経由で TerminalWindow/AppHost へ通知)
           │
           └─ IslandWindow::IsQuakeWindow(true) (IslandWindow.cpp:1631)
                  │
                  ├─ IslandWindow::_enterQuakeMode() (IslandWindow.cpp:1656)
                  │      │
                  │      ├─ MonitorFromRect() [Win32 API]
                  │      │
                  │      ├─ IslandWindow::_getQuakeModeSize(hmon) (IslandWindow.cpp:1686)
                  │      │      │
                  │      │      ├─ GetMonitorInfo() [Win32 API]
                  │      │      └─ GetTotalNonClientExclusiveSize() [DPIサイズ計算]
                  │      │
                  │      └─ SetWindowPos() [Win32 API]
                  │
                  └─ _OnSizing() / _OnMoving() [リサイズ・移動制限]
```

### データフロー図

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

QuakeModeアクション ───▶ _HandleQuakeMode ───▶ IsQuakeWindow setter
                                                     │
                                                     ▼
                                              _enterQuakeMode
                                                     │
                                                     ▼
モニター情報 ──────────▶ _getQuakeModeSize ───▶ ウィンドウ位置・サイズ
(MONITORINFO)                                   (RECT → SetWindowPos)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AppActionHandlers.cpp | `src/cascadia/TerminalApp/AppActionHandlers.cpp` | ソース | QuakeModeアクションハンドラ |
| IslandWindow.h | `src/cascadia/WindowsTerminal/IslandWindow.h` | ヘッダー | Quakeモード関連メンバー宣言 |
| IslandWindow.cpp | `src/cascadia/WindowsTerminal/IslandWindow.cpp` | ソース | Quakeモードのウィンドウ管理実装 |
| TerminalWindow.cpp | `src/cascadia/TerminalApp/TerminalWindow.cpp` | ソース | QuakeModeアクションのTerminalWindowレベル処理 |
| AllShortcutActions.h | `src/cascadia/TerminalSettingsModel/AllShortcutActions.h` | ヘッダー | QuakeModeアクション定義 |
| defaults.json | `src/cascadia/TerminalSettingsModel/defaults.json` | 設定 | デフォルトキーバインド定義 |
