From 5d9554780f2a5c2b4fbaabda68e88d0bee1fec58 Mon Sep 17 00:00:00 2001 From: yuanyuanxiang <962914132@qq.com> Date: Thu, 14 May 2026 22:42:19 +0200 Subject: [PATCH] Fix(Web): Map unshifted OEM symbols, send multi-char IME commits --- server/2015Remote/WebPage.h | 58 +++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/server/2015Remote/WebPage.h b/server/2015Remote/WebPage.h index 72be981..25e0da3 100644 --- a/server/2015Remote/WebPage.h +++ b/server/2015Remote/WebPage.h @@ -2916,35 +2916,37 @@ inline std::string GetWebPageHTML() { sendKey(e.keyCode, false, e.altKey); }); + // 字符 → Win32 VK 映射表(提到 listener 外避免每次输入重建)。 + // US 键盘上"不需要 Shift"的 OEM 符号 ASCII 码 ≠ VK 码,必须显式映射。 + const SHIFT_SYMBOLS = '~!@#$%^&*()_+{}|:"<>?'; + const SYMBOL_VK_MAP = { + // —— Unshifted OEM symbols (US layout) —— + '`': 192, '-': 189, '=': 187, '[': 219, ']': 221, '\\': 220, + ';': 186, "'": 222, ',': 188, '.': 190, '/': 191, + // —— Shifted symbols (与 above 共享 VK,多了 Shift 修饰) —— + '~': 192, '!': 49, '@': 50, '#': 51, '$': 52, '%': 53, + '^': 54, '&': 55, '*': 56, '(': 57, ')': 48, '_': 189, + '+': 187, '{': 219, '}': 221, '|': 220, ':': 186, + '"': 222, '<': 188, '>': 190, '?': 191 + }; + + // 把单个字符发成一对 keyDown/keyUp(必要时夹一对 Shift) + function sendCharAsKey(ch) { + const isUpperCase = ch >= 'A' && ch <= 'Z'; + const needsShift = isUpperCase || SHIFT_SYMBOLS.includes(ch); + const keyCode = SYMBOL_VK_MAP[ch] || ch.toUpperCase().charCodeAt(0); + if (needsShift) sendKey(16, true); // VK_SHIFT = 16 + sendKey(keyCode, true); + sendKey(keyCode, false); + if (needsShift) sendKey(16, false); + } + mobileKeyboard.addEventListener('input', function(e) { - const char = e.data; - if (char) { - // Check if character needs Shift key - const isUpperCase = char >= 'A' && char <= 'Z'; - const shiftSymbols = '~!@#$%^&*()_+{}|:"<>?'; - const needsShift = isUpperCase || shiftSymbols.includes(char); - - // Map symbols to their base keys - const symbolMap = { - '~': 192, '!': 49, '@': 50, '#': 51, '$': 52, '%': 53, - '^': 54, '&': 55, '*': 56, '(': 57, ')': 48, '_': 189, - '+': 187, '{': 219, '}': 221, '|': 220, ':': 186, - '"': 222, '<': 188, '>': 190, '?': 191 - }; - - let keyCode; - if (symbolMap[char]) { - keyCode = symbolMap[char]; - } else { - keyCode = char.toUpperCase().charCodeAt(0); - } - - // Send Shift down if needed - if (needsShift) sendKey(16, true); // VK_SHIFT = 16 - sendKey(keyCode, true); - sendKey(keyCode, false); - // Send Shift up if needed - if (needsShift) sendKey(16, false); + // e.data 可能携带多个字符(中/日/韩 IME 候选词上屏、Gboard 滑行输入、 + // 剪贴板粘贴一段文本都会一次性 commit)。逐字符发送,保证每个都到达 host。 + const text = e.data; + if (text) { + for (const ch of text) sendCharAsKey(ch); } mobileKeyboard.value = ''; });