# Input and Keyboard This page documents the simulated input stack: pointer events, soft keyboard state, IME behavior, and the `adjustResize` layout contract. For service API signatures, see [`README.md`](README.md). For app UI rules, see [`../../app/module-contract.md`](../../app/module-contract.md). ## Components | Area | Implementation | Responsibility | |---|---|---| | Soft keyboard state | `os/keyboard/KeyboardService.ts` | Volatile store for visibility, height, and mode. | | Keyboard overlay UI | `os/components/KeyboardOverlay.tsx` | Renders the keyboard, handles focus, text insertion, dismissal, and smart scroll. | | Activity resize | `os/SystemShell.tsx` | Wraps each Activity in `data-adjust-resize` and shrinks the active one by keyboard height. | | Global hide rule | `app.css` | Hides `[data-hide-on-keyboard]` inside an active resize container. | | IME dictionary | `os/keyboard/pinyinData.ts`, `os/keyboard/pinyinLargeDict.ts`, `os/keyboard/pinyinIme.ts` | Chinese pinyin candidate generation. | | IME build script | `scripts/ime/build_pinyin_dict.mjs` | Generates the large pinyin dictionary from source dictionaries. | ## KeyboardService `KeyboardService` is exposed as `window.__OS__.keyboard`. ```ts __OS__.keyboard.show(); __OS__.keyboard.hide(); __OS__.keyboard.isVisible(); __OS__.keyboard.getHeight(); __OS__.keyboard.setHeight(280); __OS__.keyboard.setMode('zh'); // or 'en' __OS__.keyboard.toggleMode(); __OS__.keyboard.subscribe(state => {}); ``` Current state shape: ```ts type KeyboardMode = 'en' | 'zh'; interface KeyboardServiceState { visible: boolean; mode: KeyboardMode; height: number; } ``` The store is volatile. Refreshing the simulator resets it to hidden, English mode, height `0`. When `show()` is called, height is set from `SIMULATOR_CONFIG.framework.keyboardHeight` unless overridden later with `setHeight()`. ## Back behavior The keyboard registers a `BackDispatcher` handler named `keyboard.dismiss` at priority `700`. When the keyboard is visible, system back hides the keyboard and consumes the event. App-level back handlers should not duplicate this behavior. ## Focus and dismissal `KeyboardOverlay` listens globally: | Event | Behavior | |---|---| | `focusin` on an editable element | Shows the keyboard and schedules smart scroll. | | `focusout` | Hides the keyboard unless the blurred editable itself is inside a `data-keep-keyboard` container. | | capture-phase `click` on an already focused editable element | Reopens or scrolls without disturbing pointer sequences. | | capture-phase `pointerdown` outside the keyboard, editable element, gesture bar, or `data-keep-keyboard` | Hides the keyboard; pointer down inside `data-keep-keyboard` does not dismiss it. | | DOM removal of the focused input | Hides the keyboard during route changes or unmounts. | Editable detection is handled inside `KeyboardOverlay`; app components generally only need ordinary ``, `