# 機能設計書 51-KeyboardDevice

## 概要

本ドキュメントは、Avaloniaフレームワークにおけるキーボードデバイス（KeyboardDevice）機能の設計仕様を定義する。KeyboardDeviceは、キーボード入力イベントの処理、フォーカス管理、およびキー状態の追跡を担当するコア入力処理コンポーネントである。

### 本機能の処理概要

KeyboardDeviceは、Avaloniaアプリケーションにおけるキーボード入力のハンドリングを一元的に管理するクラスである。プラットフォームから受信した生のキーボードイベントを処理し、適切なUI要素にルーティングされたイベントとして配信する。

**業務上の目的・背景**：デスクトップアプリケーションやモバイルアプリケーションにおいて、キーボード入力は最も基本的なユーザーインタラクション手段の一つである。KeyboardDeviceは、クロスプラットフォームで一貫したキーボード入力処理を提供し、開発者がプラットフォーム固有の実装を意識することなくキーボードイベントを処理できるようにする。これにより、ショートカットキー、フォーム入力、ナビゲーションなどの機能を統一的に実装できる。

**機能の利用シーン**：
- テキスト入力フィールドでの文字入力処理
- ショートカットキー（Ctrl+C、Ctrl+V等）の検出と実行
- キーボードによるUI要素間のフォーカス移動
- ゲームやカスタムコントロールでのキー入力検出

**主要な処理内容**：
1. プラットフォームからの生キーボードイベント（RawKeyEventArgs）の受信と解析
2. フォーカスされた要素の追跡と管理（FocusedElement）
3. KeyDownイベントとKeyUpイベントの生成とルーティング
4. テキスト入力イベント（TextInputEvent）の処理
5. キーバインディングのマッチングと実行
6. IsKeyboardFocusWithinプロパティの管理

**関連システム・外部連携**：InputManager、FocusManager、TextInputMethodManagerと連携し、入力処理パイプラインを構成する。プラットフォーム層（Win32、X11、Cocoa等）から生イベントを受信する。

**権限による制御**：特になし。すべてのUIコンポーネントがキーボード入力を受信可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | Accelerator | 補助機能 | キーボード入力の処理とキー状態管理 |

## 機能種別

入力デバイス管理 / イベント処理 / フォーカス管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| RawKeyEventArgs | RawKeyEventArgs | Yes | 生キーイベントデータ | nullチェック |
| RawTextInputEventArgs | RawTextInputEventArgs | No | 生テキスト入力データ | nullチェック |

### 入力データソース

- プラットフォーム固有のキーボードドライバ（Win32、X11、Cocoa、Android、iOS等）
- InputManager経由で配信される生入力イベント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| KeyEventArgs | KeyEventArgs | KeyDown/KeyUpイベント引数 |
| TextInputEventArgs | TextInputEventArgs | テキスト入力イベント引数 |
| FocusedElement | IInputElement? | 現在フォーカスされている要素 |

### 出力先

- フォーカスされたInputElement（イベント配信先）
- PropertyChangedイベント（FocusedElement変更時）

## 処理フロー

### 処理シーケンス

```
1. ProcessRawEvent受信
   └─ RawInputEventArgsをKeyboardDeviceが受信
2. イベント種別判定
   └─ RawKeyEventArgsまたはRawTextInputEventArgsかを判定
3. フォーカス要素取得
   └─ FocusedElement ?? e.Root.RootElementでターゲット決定
4. キーバインディング処理（KeyDown時）
   └─ ビジュアルツリーを上位に辿りながらKeyBindingsをチェック
5. ルーテッドイベント生成・発火
   └─ KeyEventArgs/TextInputEventArgsを生成してRaiseEvent
6. ハンドル状態反映
   └─ イベントのHandledプロパティを生イベントに反映
```

### フローチャート

```mermaid
flowchart TD
    A[ProcessRawEvent開始] --> B{イベントがHandled?}
    B -->|Yes| Z[処理終了]
    B -->|No| C{RawKeyEventArgs?}
    C -->|Yes| D[フォーカス要素取得]
    C -->|No| E{RawTextInputEventArgs?}
    D --> F{KeyDown?}
    F -->|Yes| G[KeyBindingsチェック]
    G --> H[KeyDownEvent発火]
    F -->|No| I[KeyUpEvent発火]
    H --> J[Handled反映]
    I --> J
    E -->|Yes| K[TextInputEvent発火]
    E -->|No| Z
    K --> J
    J --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-51-01 | フォーカス要素優先 | キーイベントはFocusedElementに優先的に配信される | FocusedElementがnullでない場合 |
| BR-51-02 | ルートへのフォールバック | FocusedElementがnullの場合はRoot.RootElementにイベント配信 | FocusedElement == null |
| BR-51-03 | キーバインディング優先 | KeyDownイベントはKeyBindingsが先に処理される | KeyBindingsが設定されている場合 |
| BR-51-04 | イベントバブリング | イベントはビジュアルツリーを上方向にバブルする | RoutingStrategies.Bubble |

### 計算ロジック

特になし

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

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

該当なし（UIフレームワークのためデータベース操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentNullException | 必須パラメータがnull | 呼び出し元でのnullチェック |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- キーイベント処理は16ms以内（60fps維持のため）
- キーバインディングの検索は最適化されたリスト走査

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

- パスワードフィールドへの入力時、TextInputイベントの内容はログに出力しない
- キーボードフックによる入力傍受は防止できない（OS/プラットフォーム層の制約）

## 備考

- KeyboardDeviceはPrivateApiとしてマークされており、直接のインスタンス化は非推奨
- AvaloniaLocator経由でシングルトンインスタンスを取得

---

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

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

### 推奨読解順序

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

キーボードイベント処理で使用される型定義を先に把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IKeyboardDevice.cs | `src/Avalonia.Base/Input/IKeyboardDevice.cs` | KeyModifiers、KeyStates、RawInputModifiersの列挙型定義、IKeyboardDeviceインターフェース |
| 1-2 | KeyEventArgs.cs | `src/Avalonia.Base/Input/KeyEventArgs.cs` | Key、PhysicalKey、KeySymbol、KeyModifiersなどキーイベントの情報構造 |
| 1-3 | Key.cs | `src/Avalonia.Base/Input/Key.cs` | 仮想キーコードの列挙型定義 |

**読解のコツ**: KeyModifiersはFlags属性を持つ列挙型で、Alt/Control/Shift/Metaの組み合わせを表現する。ビット演算で複合キー状態を判定する。

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

キーボード入力処理の開始点を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | KeyboardDevice.cs | `src/Avalonia.Base/Input/KeyboardDevice.cs` | ProcessRawEventメソッドがエントリーポイント |

**主要処理フロー**:
1. **223-227行目**: ProcessRawEventの入口、Handledチェック
2. **228行目**: フォーカス要素の取得（FocusedElement ?? e.Root.RootElement）
3. **230-288行目**: RawKeyEventArgsの処理（KeyDown/KeyUp）
4. **252-282行目**: KeyBindingsのマッチングと実行
5. **284行目**: ルーテッドイベントの発火
6. **290-301行目**: RawTextInputEventArgsの処理

#### Step 3: フォーカス管理を理解する

キーボードフォーカスの制御ロジックを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | KeyboardDevice.cs | `src/Avalonia.Base/Input/KeyboardDevice.cs` | SetFocusedElementメソッド（131-216行目） |

**主要処理フロー**:
- **140-144行目**: SetFocusedElementのシグネチャ、isFocusChangeCancellableパラメータ
- **152-166行目**: LosingFocusイベントの発火とキャンセル処理
- **168-187行目**: GettingFocusイベントの発火
- **189-215行目**: 実際のフォーカス変更処理、LostFocus/GotFocusイベント発火

#### Step 4: IsKeyboardFocusWithin管理を理解する

フォーカス状態の祖先要素への伝播を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | KeyboardDevice.cs | `src/Avalonia.Base/Input/KeyboardDevice.cs` | SetIsFocusWithinメソッド（68-109行目） |

**主要処理フロー**:
- **70-74行目**: newElementがnullの場合、祖先のフォーカス状態をクリア
- **78-89行目**: 共通祖先（branch）の探索
- **91-96行目**: 古い要素の子孫のフォーカス状態クリア
- **98-108行目**: 新しい要素から祖先までIsKeyboardFocusWithin = trueを設定

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

```
InputManager.ProcessRawEvent
    │
    └─ KeyboardDevice.ProcessRawEvent
           │
           ├─ RawKeyEventArgs処理
           │      ├─ KeyBindingsチェック
           │      │      └─ KeyBinding.TryHandle
           │      │             └─ ICommand.Execute
           │      └─ element.RaiseEvent(KeyEventArgs)
           │
           └─ RawTextInputEventArgs処理
                  └─ element.RaiseEvent(TextInputEventArgs)
```

### データフロー図

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

RawKeyEventArgs ───▶ KeyboardDevice ───▶ KeyEventArgs
                     ├─ Key変換              │
                     ├─ Modifiers変換        └─▶ FocusedElement.RaiseEvent
                     └─ KeyBindings検索

RawTextInputEventArgs ───▶ KeyboardDevice ───▶ TextInputEventArgs
                           └─ Text抽出          └─▶ FocusedElement.RaiseEvent
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| KeyboardDevice.cs | `src/Avalonia.Base/Input/KeyboardDevice.cs` | ソース | メインクラス、キーボード入力処理 |
| IKeyboardDevice.cs | `src/Avalonia.Base/Input/IKeyboardDevice.cs` | ソース | インターフェース定義、KeyModifiers列挙型 |
| KeyEventArgs.cs | `src/Avalonia.Base/Input/KeyEventArgs.cs` | ソース | キーイベント引数クラス |
| Key.cs | `src/Avalonia.Base/Input/Key.cs` | ソース | 仮想キーコード列挙型 |
| PhysicalKey.cs | `src/Avalonia.Base/Input/PhysicalKey.cs` | ソース | 物理キーコード列挙型 |
| KeyBinding.cs | `src/Avalonia.Base/Input/KeyBinding.cs` | ソース | キーバインディング定義 |
| KeyGesture.cs | `src/Avalonia.Base/Input/KeyGesture.cs` | ソース | キージェスチャー定義 |
| InputElement.cs | `src/Avalonia.Base/Input/InputElement.cs` | ソース | 入力要素基底クラス、イベント定義 |
| TextInputMethodManager.cs | `src/Avalonia.Base/Input/TextInput/InputMethodManager.cs` | ソース | テキスト入力メソッド管理 |
| FocusManager.cs | `src/Avalonia.Base/Input/FocusManager.cs` | ソース | フォーカス管理 |
