# 機能設計書 46-Screens

## 概要

本ドキュメントは、Avalonia UIフレームワークにおけるScreens（画面管理）機能の設計仕様を定義する。Screensクラスはデバイス上で利用可能なすべてのディスプレイ（スクリーン）を管理し、マルチモニター環境をサポートする。

### 本機能の処理概要

Screensクラスは、システムに接続されたすべてのディスプレイ情報を管理するクラスである。プライマリスクリーンの取得、特定の座標やウィンドウが存在するスクリーンの検出、スクリーン変更イベントの通知などを提供する。

**業務上の目的・背景**：マルチモニター環境はビジネスアプリケーションで一般的である。ウィンドウを適切なモニターに配置したり、モニターごとの解像度やDPIに対応するために、スクリーン情報へのアクセスが必要となる。

**機能の利用シーン**：ウィンドウの初期位置決定、マルチモニター対応レイアウト、モニター変更検出（ホットプラグ）、特定コントロールが表示されているモニターの取得など。

**主要な処理内容**：
1. 利用可能なスクリーン一覧の取得
2. プライマリスクリーンの取得
3. 座標、矩形、ウィンドウ、ビジュアルからのスクリーン検出
4. スクリーン変更イベントの通知
5. 詳細スクリーン情報のリクエスト（権限が必要な場合あり）

**関連システム・外部連携**：IScreenImpl（プラットフォーム実装）、Window、TopLevelと連携する。

**権限による制御**：一部プラットフォームでは詳細スクリーン情報の取得に権限が必要。RequestScreenDetails()で権限リクエスト可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 64 | Window Customizations | 参照画面 | ウィンドウの画面配置に使用 |

## 機能種別

システム情報取得 / マルチモニター対応 / イベント通知

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| bounds | PixelRect | Yes（ScreenFromBounds用） | 検索対象の矩形 | - |
| window | WindowBase | Yes（ScreenFromWindow用） | 検索対象のウィンドウ | null不可 |
| topLevel | TopLevel | Yes（ScreenFromTopLevel用） | 検索対象のTopLevel | null不可 |
| point | PixelPoint | Yes（ScreenFromPoint用） | 検索対象の座標 | - |
| visual | Visual | Yes（ScreenFromVisual用） | 検索対象のビジュアル | null不可 |

### 入力データソース

- IScreenImpl: プラットフォーム固有のスクリーン実装

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ScreenCount | int | 利用可能なスクリーン数 |
| All | IReadOnlyList<Screen> | すべてのスクリーンのリスト |
| Primary | Screen? | プライマリスクリーン |

### 出力先

- イベント: Changed（スクリーン構成変更時）

## 処理フロー

### 処理シーケンス

```
1. Screens インスタンス取得
   └─ TopLevel.Screens または Application経由

2. スクリーン情報の取得
   └─ All、Primary、ScreenCount

3. 特定スクリーンの検索
   └─ ScreenFromPoint、ScreenFromBounds等

4. スクリーン変更の監視
   └─ Changedイベント購読
```

### フローチャート

```mermaid
flowchart TD
    A[Screens取得] --> B{操作種別}
    B -->|情報取得| C[All/Primary/ScreenCount]
    B -->|スクリーン検索| D{検索方法}
    D -->|座標| E[ScreenFromPoint]
    D -->|矩形| F[ScreenFromBounds]
    D -->|ウィンドウ| G[ScreenFromWindow]
    D -->|Visual| H[ScreenFromVisual]
    E --> I[Screen返却]
    F --> I
    G --> I
    H --> I
    B -->|変更監視| J[Changedイベント購読]
    J --> K[イベントハンドラ実行]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | モバイル制限 | モバイルではScreenFromBounds/ScreenFromPointがnullを返す | iOS/Android |
| BR-002 | 遅延購読 | Changedイベントはハンドラ追加時にのみプラットフォーム購読 | パフォーマンス最適化 |
| BR-003 | プライマリ優先 | Primary取得はIsPrimary=trueの最初のスクリーン | 常時適用 |

### 計算ロジック

**ScreenFromVisualの処理**：
```
1. VisualからTopLevelを取得
2. TopLevelがWindowBaseの場合：
   - VisualのBoundsをスクリーン座標に変換
   - ScreenFromBoundsでスクリーン検索
   - 見つからない場合はScreenFromTopLevelにフォールバック
3. それ以外の場合：
   - ScreenFromTopLevelを使用
```

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentNullException | window/topLevel/visualがnull | 有効なインスタンスを渡す |
| - | ObjectDisposedException | PlatformImplが破棄済み | TopLevelが有効か確認 |
| - | ArgumentException | Visualがビジュアルツリーに未接続 | 接続後に呼び出す |

### リトライ仕様

リトライは適用されない。

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

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

## パフォーマンス要件

- スクリーン情報の取得は即座に完了
- Changedイベントはプラットフォームからの通知と同期

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

- 一部プラットフォームでは詳細スクリーン情報に権限が必要
- RequestScreenDetails()でユーザーに権限を求めるダイアログが表示される可能性あり

## 備考

- モバイルプラットフォームでは機能制限あり
- 仮想デスクトップ環境での動作はプラットフォーム依存

---

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

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

### 推奨読解順序

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

Screensクラスの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | フィールド | `src/Avalonia.Controls/Screens.cs` | 16-17行目。IScreenImplとイベントハンドラ |
| 1-2 | プロパティ | `src/Avalonia.Controls/Screens.cs` | 22-32行目。ScreenCount、All、Primary |

**読解のコツ**: _iScreenImplがプラットフォーム実装へのブリッジ。

#### Step 2: スクリーン検索メソッドを理解する

各種ScreenFrom系メソッドの実装。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ScreenFromBounds | `src/Avalonia.Controls/Screens.cs` | 74-77行目。矩形からスクリーン検索 |
| 2-2 | ScreenFromWindow | `src/Avalonia.Controls/Screens.cs` | 85-97行目。ウィンドウからスクリーン検索 |
| 2-3 | ScreenFromTopLevel | `src/Avalonia.Controls/Screens.cs` | 105-117行目。TopLevelからスクリーン検索 |
| 2-4 | ScreenFromPoint | `src/Avalonia.Controls/Screens.cs` | 127-130行目。座標からスクリーン検索 |
| 2-5 | ScreenFromVisual | `src/Avalonia.Controls/Screens.cs` | 137-163行目。Visualからスクリーン検索 |

**主要処理フロー**:
- **87-90行目**: windowのnullチェック
- **91-94行目**: PlatformImplのnullチェック（ObjectDisposedException）
- **96行目**: プラットフォーム実装への委譲

#### Step 3: イベント処理を理解する

スクリーン変更イベントの仕組み。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Changedイベント | `src/Avalonia.Controls/Screens.cs` | 37-55行目。遅延購読パターン |

**主要処理フロー**:
- **41-44行目**: 最初のハンドラ追加時にプラットフォーム購読
- **49-53行目**: 最後のハンドラ削除時にプラットフォーム購読解除

#### Step 4: 補助機能を理解する

権限リクエストと内部ヘルパー。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | RequestScreenDetails | `src/Avalonia.Controls/Screens.cs` | 173行目。詳細情報リクエスト |
| 4-2 | ImplChanged | `src/Avalonia.Controls/Screens.cs` | 175-178行目。イベント発火ヘルパー |

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

```
Screens
    │
    ├─ プロパティアクセス
    │      ├─ ScreenCount → _iScreenImpl.ScreenCount
    │      ├─ All → _iScreenImpl.AllScreens
    │      └─ Primary → All.FirstOrDefault(x => x.IsPrimary)
    │
    ├─ スクリーン検索
    │      ├─ ScreenFromBounds(rect)
    │      │      └─ _iScreenImpl.ScreenFromRect
    │      ├─ ScreenFromWindow(window)
    │      │      └─ _iScreenImpl.ScreenFromWindow
    │      ├─ ScreenFromTopLevel(topLevel)
    │      │      └─ _iScreenImpl.ScreenFromTopLevel
    │      ├─ ScreenFromPoint(point)
    │      │      └─ _iScreenImpl.ScreenFromPoint
    │      └─ ScreenFromVisual(visual)
    │             ├─ TopLevel.GetTopLevel
    │             ├─ visual.PointToScreen
    │             ├─ ScreenFromBounds
    │             └─ ScreenFromTopLevel (フォールバック)
    │
    └─ イベント
           └─ Changed → _iScreenImpl.Changed購読
```

### データフロー図

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

座標/矩形/Window ───────▶ ScreenFromXxx ──────────────▶ Screen?
                              │
                              ▼
                    IScreenImpl呼び出し
                              │
                              ▼
                    プラットフォーム実装
                              │
                              ▼
                         [Screen情報]

プラットフォーム変更 ────▶ Changed イベント
                              │
                              ▼
                    [ハンドラ実行]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Screens.cs | `src/Avalonia.Controls/Screens.cs` | ソース | Screensクラスの実装 |
| Screen.cs | `src/Avalonia.Controls/Screen.cs` | ソース | 個別スクリーン情報 |
| IScreenImpl.cs | `src/Avalonia.Controls/Platform/IScreenImpl.cs` | ソース | プラットフォームインターフェース |
| PixelRect.cs | `src/Avalonia.Base/PixelRect.cs` | ソース | ピクセル座標矩形 |
| PixelPoint.cs | `src/Avalonia.Base/PixelPoint.cs` | ソース | ピクセル座標点 |
