feat(core+host+android): committed-text input plane (IME path) — InputKind::TextInput
The VK key-event vocabulary cannot express text an input method COMMITS (autocorrect, gesture typing, non-Latin scripts, emoji). Add a first-class text event and negotiate it: - punktfunk-core: InputKind::TextInput (= 15) carries one Unicode scalar per event in `code`; HOST_CAP_TEXT_INPUT (0x04) in Welcome::host_caps. - Host advertises the cap only where the session's inject backend can type text: Windows SendInput (KEYEVENTF_UNICODE, surrogate-pair aware) and the Linux wlroots backend — a dedicated second zwp_virtual_keyboard whose xkb keymap grows Unicode keysyms on demand (the wtype model), so keymap re-uploads never disturb the main device's layout/modifier state. The KWin-fake-input/libei/gamescope backends can only press layout keycodes, so those sessions don't set the bit and clients keep the VK fallback. - GameStream plane: Moonlight's UTF-8 text packet (MAGIC_UTF8, previously recognized-and-dropped) now decodes to the same TextInput events. - Android: KeyCaptureView picks a real editable InputConnection when the host has the cap — the IME runs its full machinery, mirrored to the host live via common-prefix diffs of the composition (backspaces + new suffix), with setComposingRegion adopting committed text so autocorrect-revert flows diff instead of retyping; newline→Enter, deleteSurroundingText→Backspace/Delete. Older hosts keep the TYPE_NULL raw-key path unchanged. - keymap: media VKs (0xB0-0xB3) → evdev so the Android media keys land on Linux hosts too. Verified: punktfunk-core + host gamestream + pf-inject tests green on Linux (Ubuntu box), clippy clean; Android app+native builds. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -287,6 +287,20 @@ object NativeBridge {
|
||||
/** One key transition. vk: Windows VK (0 = dropped by Rust). mods: VK modifier mask (0 for now). */
|
||||
external fun nativeSendKey(handle: Long, vk: Int, down: Boolean, mods: Int)
|
||||
|
||||
/**
|
||||
* Whether the host advertised committed-text injection (`HOST_CAP_TEXT_INPUT`) — its inject
|
||||
* backend can type Unicode text directly. Picks the real IME `InputConnection` (autocorrect,
|
||||
* gesture typing, non-Latin scripts) over the TYPE_NULL raw-key fallback. False on `0`.
|
||||
*/
|
||||
external fun nativeTextInputSupported(handle: Long): Boolean
|
||||
|
||||
/**
|
||||
* Committed IME text → one `TextInput` wire event per Unicode scalar, in order. Control
|
||||
* characters are skipped natively (Enter/Backspace ride [nativeSendKey]). Only meaningful
|
||||
* when [nativeTextInputSupported] returned true — older hosts ignore the events.
|
||||
*/
|
||||
external fun nativeSendText(handle: Long, text: String)
|
||||
|
||||
// ---- Gamepad: each controller forwarded on its own wire pad index (0..15, low byte of flags) ----
|
||||
// The pad index is assigned per Android device by GamepadRouter; a single controller lands on 0,
|
||||
// so its wire is byte-identical to the old single-pad path. The core folds the per-transition
|
||||
|
||||
Reference in New Issue
Block a user