Fix(Web): Map unshifted OEM symbols, send multi-char IME commits
This commit is contained in:
@@ -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 = '';
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user