fix: correct keyboard scancode mapping from KeyTranslator.java
All checks were successful
CI / fmt (push) Successful in 39s
Publish / frontend (push) Successful in 45s
CI / check (push) Successful in 1m22s
CI / clippy (push) Successful in 1m38s
Publish / backend (push) Successful in 2m48s

The mapping was built assuming keynr followed physical keyboard order
with Escape=0. In reality, KeyTranslator.java maps Java VK_* codes to
keynr values with a different layout:

- keynr 0 = Backquote (not Escape)
- keynr 59 = Escape
- keynr 27 = Enter (not 40)
- keynr 40 = Backslash (not 42)

This caused the number row and QWERTY row to be off by 1 (Escape
was inserted at position 0, pushing everything). The home row
(CapsLock=28, A=29...L=37) happened to align by coincidence, which
is why 'g'(33) worked but 'r'(should be 18, was 19=T) didn't.

Also fixes: F1-F12 off by 1, PrintScreen/ScrollLock/Pause off by 1,
numpad operator keys swapped with numpad 7/8/9.

Corrected both Rust (input.rs) and TypeScript (input.ts) mappings
to match the authoritative KeyTranslator.java VK→keynr table.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-07 10:42:02 +03:00
parent 4f7d69c75a
commit 75a51def79
2 changed files with 111 additions and 88 deletions

View File

@@ -1,47 +1,59 @@
// JavaScript KeyboardEvent.code → e-RIC scancode (KbdLayout_104pc)
// Derived from KeyTranslator.java line 14 (Java VK_* → keynr table).
// Must match crates/ericrfb/src/input.rs js_code_to_scancode()
const KEY_MAP: Record<string, number> = {
Escape: 0,
F1: 59, F2: 60, F3: 61, F4: 62, F5: 63, F6: 64,
F7: 65, F8: 66, F9: 67, F10: 68, F11: 69, F12: 70,
// Number row (keynr 0-13)
Backquote: 0,
Digit1: 1, Digit2: 2, Digit3: 3, Digit4: 4, Digit5: 5,
Digit6: 6, Digit7: 7, Digit8: 8, Digit9: 9, Digit0: 10,
Minus: 11, Equal: 12, Backspace: 13,
Backquote: 1,
Digit1: 2, Digit2: 3, Digit3: 4, Digit4: 5, Digit5: 6,
Digit6: 7, Digit7: 8, Digit8: 9, Digit9: 10, Digit0: 11,
Minus: 12, Equal: 13, Backspace: 14,
Tab: 15,
KeyQ: 16, KeyW: 17, KeyE: 18, KeyR: 19, KeyT: 20,
KeyY: 21, KeyU: 22, KeyI: 23, KeyO: 24, KeyP: 25,
BracketLeft: 26, BracketRight: 27,
// QWERTY row (keynr 14-27)
Tab: 14,
KeyQ: 15, KeyW: 16, KeyE: 17, KeyR: 18, KeyT: 19,
KeyY: 20, KeyU: 21, KeyI: 22, KeyO: 23, KeyP: 24,
BracketLeft: 25, BracketRight: 26, Enter: 27,
// Home row (keynr 28-40)
CapsLock: 28,
KeyA: 29, KeyS: 30, KeyD: 31, KeyF: 32, KeyG: 33,
KeyH: 34, KeyJ: 35, KeyK: 36, KeyL: 37,
Semicolon: 38, Quote: 39, Enter: 40,
Semicolon: 38, Quote: 39, Backslash: 40,
ShiftLeft: 41, Backslash: 42,
// Bottom row (keynr 41-53)
ShiftLeft: 41,
KeyZ: 43, KeyX: 44, KeyC: 45, KeyV: 46, KeyB: 47,
KeyN: 48, KeyM: 49, Comma: 50, Period: 51, Slash: 52,
ShiftRight: 53,
ControlLeft: 54, MetaLeft: 105, AltLeft: 55,
Space: 56,
AltRight: 57, MetaRight: 106, ControlRight: 58,
// Modifiers (keynr 54-58)
ControlLeft: 54, AltLeft: 55, Space: 56,
AltRight: 57, ControlRight: 58,
PrintScreen: 71, ScrollLock: 72, Pause: 73,
// Escape + Function keys (keynr 59-71)
Escape: 59,
F1: 60, F2: 61, F3: 62, F4: 63, F5: 64, F6: 65,
F7: 66, F8: 67, F9: 68, F10: 69, F11: 70, F12: 71,
// Navigation cluster (keynr 72-84)
PrintScreen: 72, ScrollLock: 73, Pause: 74,
Insert: 75, Home: 76, PageUp: 77,
Delete: 78, End: 79, PageDown: 80,
ArrowUp: 81, ArrowLeft: 82, ArrowDown: 83, ArrowRight: 84,
NumLock: 85, NumpadDivide: 86, NumpadMultiply: 87, NumpadSubtract: 88,
NumpadAdd: 89, NumpadEnter: 98,
Numpad7: 90, Numpad8: 94, Numpad9: 99,
// Numpad (keynr 85-101)
NumLock: 85,
Numpad7: 86, Numpad8: 87, Numpad9: 88,
NumpadAdd: 89, NumpadDivide: 90,
Numpad4: 91, Numpad5: 92, Numpad6: 93,
NumpadMultiply: 94,
Numpad1: 95, Numpad2: 96, Numpad3: 97,
NumpadEnter: 98, NumpadSubtract: 99,
Numpad0: 100, NumpadDecimal: 101,
// Windows/Meta keys (keynr 105-106)
MetaLeft: 105, MetaRight: 106,
}
export function codeToScancode(code: string): number | undefined {