Fix(Web): Map unshifted OEM symbols, send multi-char IME commits

This commit is contained in:
yuanyuanxiang
2026-05-14 22:42:19 +02:00
parent 84a52b9dcf
commit 5d9554780f

View File

@@ -2916,35 +2916,37 @@ inline std::string GetWebPageHTML() {
sendKey(e.keyCode, false, e.altKey); 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) { mobileKeyboard.addEventListener('input', function(e) {
const char = e.data; // e.data 可能携带多个字符(中/日/韩 IME 候选词上屏、Gboard 滑行输入、
if (char) { // 剪贴板粘贴一段文本都会一次性 commit。逐字符发送保证每个都到达 host。
// Check if character needs Shift key const text = e.data;
const isUpperCase = char >= 'A' && char <= 'Z'; if (text) {
const shiftSymbols = '~!@#$%^&*()_+{}|:"<>?'; for (const ch of text) sendCharAsKey(ch);
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);
} }
mobileKeyboard.value = ''; mobileKeyboard.value = '';
}); });