# 機能設計書 259-imgui_impl_osx

## 概要

本ドキュメントは、Dear ImGuiライブラリにおけるmacOS/Cocoaプラットフォームバックエンド（imgui_impl_osx）の設計仕様を定義する。

### 本機能の処理概要

imgui_impl_osxは、macOSのCocoa/AppKitフレームワークを使用してDear ImGuiにプラットフォーム機能を提供するネイティブバックエンドモジュールである。Objective-C++で実装され、マウス（ペン入力識別可能）、キーボード、ゲームパッド入力の処理、マウスカーソル形状の制御、クリップボードアクセス、IMEサポートなどを実装する。

**業務上の目的・背景**：
macOS専用アプリケーションにおいて、GLFWやSDLなどの抽象化ライブラリを使用せず、直接Cocoaフレームワークを使用したい場合に本バックエンドを使用する。Metal、OpenGL、Vulkanなどの描画バックエンドと組み合わせて使用する。

**機能の利用シーン**：
- macOSネイティブアプリケーション開発
- Metalを使用するmacOSアプリケーション
- macOS固有機能を活用したい場合
- 他のプラットフォームへの移植が不要な場合

**主要な処理内容**：
1. バックエンドの初期化（ImGui_ImplOSX_Init）
2. 毎フレームの更新処理（ImGui_ImplOSX_NewFrame）
3. NSEventの処理（ローカルモニター経由）
4. マウスカーソル形状の制御
5. ゲームパッド入力の処理（GameControllerフレームワーク）
6. クリップボードアクセス（NSPasteboard）
7. IMEサポート（NSTextInputClient）

**関連システム・外部連携**：
- Cocoa/AppKitフレームワーク
- GameControllerフレームワーク（ゲームパッド）
- Carbon/HIToolbox（キーコード）
- 描画バックエンド（Metal、OpenGL、Vulkan等）と併用

**権限による制御**：
GameControllerフレームワークへのリンクが必要（"-framework GameController"）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 全てのImGuiウィンドウの基盤として機能 |

## 機能種別

プラットフォームバックエンド

## 入力仕様

### 入力パラメータ

#### ImGui_ImplOSX_Init

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| view | NSView* | Yes | Cocoaビューハンドル | 有効なビュー |

#### ImGui_ImplOSX_NewFrame

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| view | NSView* | No | Cocoaビューハンドル（NULL可） | - |

### 入力データソース

- NSEvent（イベント処理、ローカルモニター経由）
- mach_absolute_time（時間計測）
- GCController（ゲームパッド状態）
- NSPasteboard（クリップボード）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ImGuiIO.DisplaySize | ImVec2 | ビューサイズ |
| ImGuiIO.DisplayFramebufferScale | ImVec2 | バッキングスケール |
| ImGuiIO.DeltaTime | float | フレーム間隔 |
| ImGuiIO（入力イベント） | - | マウス/キーボード/ゲームパッドイベント |

### 出力先

ImGuiIO構造体への入力イベント登録

## 処理フロー

### 処理シーケンス

```
1. 初期化（ImGui_ImplOSX_Init）
   ├─ バックエンドデータ構造の確保
   ├─ ImGuiIO設定（バックエンド名、フラグ）
   ├─ マウスカーソル作成（未公開API含む）
   ├─ クリップボードハンドラ設定
   ├─ NSNotificationCenter登録（フォーカス）
   ├─ KeyEventResponder追加（IME）
   ├─ トラッキングエリア追加
   └─ IMEハンドラ設定
2. イベント処理（NSLocalEventMonitor経由）
   ├─ NSEventTypeMouseDown/Up処理
   ├─ NSEventTypeMouseMoved/Dragged処理
   ├─ NSEventTypeScrollWheel処理
   ├─ NSEventTypeKeyDown/Up処理
   └─ NSEventTypeFlagsChanged処理
3. フレーム更新（ImGui_ImplOSX_NewFrame）
   ├─ ビューサイズ・バッキングスケール取得
   ├─ デルタタイム計算
   ├─ マウスカーソル形状更新
   ├─ ゲームパッド状態更新
   └─ IME位置更新
4. 終了処理（ImGui_ImplOSX_Shutdown）
   ├─ NSNotificationCenter解除
   ├─ イベントモニター解除
   └─ バックエンドデータ解放
```

### フローチャート

```mermaid
flowchart TD
    A[ImGui_ImplOSX_Init] --> B[NSRunLoop]
    B --> C[NSLocalEventMonitor]
    C --> D[ImGui_ImplOSX_HandleEvent]
    D --> E[ImGui_ImplOSX_NewFrame]
    E --> F[ImGui処理]
    F --> G[描画]
    G --> B
    H[Shutdown] --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-259-01 | レンダラー併用必須 | 描画バックエンドと併用必須 | 常に適用 |
| BR-259-02 | ビュー階層必須 | NSViewが有効である必要 | 初期化時 |
| BR-259-03 | ウィンドウ限定 | イベントはビューのウィンドウに限定 | イベント処理時 |
| BR-259-04 | GameControllerリンク | ゲームパッド使用時はフレームワークリンク必須 | ゲームパッド使用時 |

### 計算ロジック

**デルタタイム計算**:
```cpp
static inline CFTimeInterval GetMachAbsoluteTimeInSeconds() {
    return (CFTimeInterval)(double)(clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1e9);
}
double current_time = GetMachAbsoluteTimeInSeconds();
io.DeltaTime = (float)(current_time - bd->Time);
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------||
| - | カーソル未公開API | 一部カーソルは未公開API | 代替カーソル使用 |
| - | スクロールキャンセル | macOS 12.1+でのスクロール減速タップ | イベント無視 |

### リトライ仕様

リトライ機能なし。

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

トランザクション管理なし

## パフォーマンス要件

- イベント処理: O(1)（イベント処理）
- NewFrame: O(1)（固定時間処理）
- NSCursor.set()は条件付き呼び出しで最適化

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

- クリップボード操作はNSPasteboard経由で安全に処理
- IME入力はNSTextInputClient経由で処理

## 備考

- macOS専用であり、移植性が必要な場合はGLFW/SDLバックエンドを推奨
- 一部カーソルは未公開APIを使用（_windowResizeNorth*Cursor等）
- macOS 12.1+でのスクロール減速タップによるジャンプ問題に対応
- 複数コンテキストは十分にテストされていない

---

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

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

### 推奨読解順序

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

バックエンドデータ構造を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | imgui_impl_osx.mm | `backends/imgui_impl_osx.mm` | ImGui_ImplOSX_Data構造体（84-96行目） |

**読解のコツ**: NSCursor配列、ImGuiObserver、KeyEventResponder、NSTextInputContextがメンバーとして含まれる。

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

初期化関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | imgui_impl_osx.h | `backends/imgui_impl_osx.h` | 関数宣言（32-34行目） |
| 2-2 | imgui_impl_osx.mm | `backends/imgui_impl_osx.mm` | ImGui_ImplOSX_Init実装（408-502行目） |

**主要処理フロー**:
1. **410-413行目**: ImGuiIOとバージョン確認
2. **416-420行目**: バックエンドデータ確保とフラグ設定
3. **427-438行目**: マウスカーソル作成（未公開API含む）
4. **443-467行目**: クリップボードハンドラ設定
5. **469-476行目**: NSNotificationCenter登録
6. **478-483行目**: KeyEventResponder追加
7. **485-499行目**: IMEハンドラ設定

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

HandleEvent関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | imgui_impl_osx.mm | `backends/imgui_impl_osx.mm` | ImGui_ImplOSX_HandleEvent実装（672-810行目） |

**主要処理フロー**:
- **679-698行目**: マウスボタンダウン/アップ処理
- **701-714行目**: マウス移動/ドラッグ処理
- **716-757行目**: スクロールホイール処理
- **759-770行目**: キーダウン/アップ処理
- **772-806行目**: フラグ変更（修飾キー）処理

#### Step 4: フレーム更新処理を理解する

NewFrame関数の実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | imgui_impl_osx.mm | `backends/imgui_impl_osx.mm` | ImGui_ImplOSX_NewFrame実装（625-650行目） |

**主要処理フロー**:
- **631-637行目**: ビューサイズ・バッキングスケール取得
- **639-645行目**: デルタタイム計算
- **647行目**: マウスカーソル更新
- **648行目**: ゲームパッド更新
- **649行目**: IME位置更新

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

```
アプリケーション
    │
    ├─ NSWindow/NSView作成
    │
    ├─ ImGui_ImplOSX_Init(view)
    │      ├─ ImGui_ImplOSX_Data確保
    │      ├─ NSCursor配列作成
    │      ├─ クリップボードハンドラ設定
    │      ├─ NSNotificationCenter登録
    │      │      ├─ onApplicationBecomeActive
    │      │      └─ onApplicationBecomeInactive
    │      ├─ KeyEventResponder追加
    │      ├─ ImGui_ImplOSX_AddTrackingArea
    │      └─ IMEハンドラ設定
    │
    ├─ メインループ（NSRunLoop）
    │      ├─ NSLocalEventMonitor
    │      │      └─ ImGui_ImplOSX_HandleEvent
    │      │              ├─ io.AddMousePosEvent
    │      │              ├─ io.AddMouseButtonEvent
    │      │              ├─ io.AddKeyEvent
    │      │              └─ io.AddMouseWheelEvent
    │      │
    │      └─ ImGui_ImplOSX_NewFrame
    │              ├─ ImGui_ImplOSX_UpdateMouseCursor
    │              ├─ ImGui_ImplOSX_UpdateGamepads
    │              └─ ImGui_ImplOSX_UpdateImePosWithView
    │
    └─ ImGui_ImplOSX_Shutdown
           ├─ NSNotificationCenter解除
           ├─ NSEvent removeMonitor
           └─ バックエンドデータ解放
```

### データフロー図

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

NSEvent ────────────────────▶ HandleEvent ───────────▶ ImGuiIO入力イベント
clock_gettime_nsec_np() ────▶ NewFrame ──────────────▶ ImGuiIO.DeltaTime
view.bounds.size ──────────▶ NewFrame ──────────────▶ ImGuiIO.DisplaySize
backingScaleFactor ─────────▶ NewFrame ──────────────▶ ImGuiIO.DisplayFramebufferScale
GCController ──────────────▶ UpdateGamepads ─────────▶ ImGuiIO入力イベント
NSPasteboard ──────────────▶ Platform_GetClipboard ──▶ クリップボードテキスト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| imgui_impl_osx.h | `backends/imgui_impl_osx.h` | ヘッダー | 関数宣言 |
| imgui_impl_osx.mm | `backends/imgui_impl_osx.mm` | ソース | 実装（Objective-C++） |
| imgui.h | `imgui.h` | ヘッダー | ImGuiIO定義 |
