# Mimo: 壁紙内のインタラクティブ UI

壁紙ウィンドウはクリックスルーで OS の key window にもなりません。そのため、壁紙内のブラウザは `pointermove` / `click` / `keydown` といった本物の DOM イベントを一切受け取れず、`<button>` は反応せず、`<input>` はフォーカスせず、dnd-kit のドラッグも開始できません。**Mimo** は Fluxlay SDK に同梱されている層で、Fluxlay の OS 入力ストリーム（`useMousePosition`, `useMouseEvents`, `useKeyboard`）を合成 DOM イベントに翻訳し、普通の React UI が壁紙内で動くようにします。

壁紙のルートを `<MimoProvider>` で 1 度ラップすれば、配線のことは忘れられます。

## こういうときに必要

壁紙にインタラクティブ UI を置くなら `<MimoProvider>` を入れてください。

- ボタン、リンク、アコーディオン、タブ
- テキスト入力（IME は [`useImeInput`](/ja/studio/developer/reference/sdk/use-ime-input.md) が処理）
- dnd-kit、react-dnd Pointer backend、Framer Motion drag
- [`useIsFocused`](/ja/studio/developer/reference/sdk/use-is-focused.md) を使ったフォーカスリング
- `onPointerDown` / `onClick` / `onKeyDown` などに依存する全て

UI を持たない純粋なビジュアル壁紙（パーティクル、時計、アニメーションアートなど）には不要です。

## クイックスタート

`MimoProvider` は別 subpath にあります。

```tsx
import { MimoProvider } from "@fluxlay/react/mimo";

export function Root() {
  return (
    <MimoProvider cursor>
      <App />
    </MimoProvider>
  );
}
```

セットアップはこれだけです。`<App />` 内では普通の React が書けます。

```tsx
function App() {
  return (
    <div>
      <button onClick={() => alert("clicked")}>クリック</button>
      <input placeholder="日本語入力もできます" />
    </div>
  );
}
```

ボタンは本当に `click` を発火し、`<input>` はクリックでフォーカスし、IME 合成も自動的に input に流れ込みます — 追加の配線は不要です。

`cursor` prop は合成 pointer に追従する仮想カーソル要素を描画します。壁紙ウィンドウ内では OS カーソルが描画されないため、ユーザに位置を示すために有効化することを推奨します。

## 仕組み

1. Fluxlay デスクトップアプリが OS レベルのマウス／キーボード入力を捕捉し、壁紙にイベントストリームとして配信。
2. `MimoProvider` は `useMousePosition` / `useMouseEvents` / `useKeyboard` でそれを subscribe。
3. 各イベントを内部の `MimoForwarder` に流し込む。
4. forwarder は DOM をヒットテストし（open shadow root も透過）、合成 `PointerEvent` / `MouseEvent` / `WheelEvent` / `KeyboardEvent` を target に dispatch。
5. React のイベントシステムは本物のイベントと同じように扱い、ハンドラを実行する。

Mimo は期待されるブラウザ挙動の大半をカバーします: `click` / `dblclick` / `contextmenu` / `auxclick`、`pointerover` / `pointerleave` の祖先連鎖、pointer capture（`setPointerCapture` 等）、pointer + keyboard 間のモディファイア伝播、movement delta、pointer cancel。

## 制限

ブラウザの `isTrusted` ゲートにより、合成イベントから trigger できない挙動があります。多くは Fluxlay 側で代替が用意されています。

| 制限                                                                                    | 代替手段                                                                                                                                 |
| --------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `<input>` / `<textarea>` の生テキスト入力（合成 `KeyboardEvent` は `value` を変えない） | IME 経路が日本語・中国語・韓国語を自動でハンドリング。直接制御は [`useImeInput`](/ja/studio/developer/reference/sdk/use-ime-input.md) を使う。 |
| OS レベルの CSS `:hover`（OS カーソルが壁紙ウィンドウに入らない）                       | `MimoProvider` に `cursor` を渡して仮想カーソルを表示する。必要に応じて hover 状態を命令的に切り替える。                                 |
| OS のコンテキストメニュー、ブラウザショートカット、autoplay 解除                        | OS chrome に頼らずアプリ内で実装する。                                                                                                   |
| HTML5 ネイティブ drag-and-drop（`draggable` 属性、`dataTransfer`、ファイルドロップ）    | dnd-kit / react-dnd Pointer backend / Framer Motion drag を使う。これらは pointer capture 経由なので動作する。                           |

## カスタマイズ

主要な設定（`pointer`, `keyboard`, `cursor`, `autoFocus`, `keyboardTarget`, `pointerCapture`、クリック閾値）は `<MimoProvider>` の props として公開されています。詳細は [`MimoProvider` リファレンス](/ja/studio/developer/reference/sdk/mimo-provider.md) を参照してください。

独自の入力 source を渡したい場合（テスト、リプレイ、Fluxlay デスクトップアプリ外での動作）は、`@fluxlay/react/mimo` からエクスポートされている低レベルな `MimoForwarderProvider` を使ってください。
