fix(macos): avoid non-selectable IME layouts for remote keys
macOS input methods can expose non-user-selectable keyboard layouts bundled with the input method rather than the user's real selectable keyboard layout. Translating remote key events through those layouts can send IME punctuation semantics to clients instead of the expected ASCII punctuation. Use the current ASCII-capable keyboard layout when the active input source has no Unicode key layout data and the reported keyboard layout is not directly selectable. Normal selectable keyboard layouts continue to use the existing translation path. This affects macOS servers forwarding keyboard input to remote clients while an input-method-bundled layout is active.
This commit is contained in:
parent
ed1306aa5d
commit
9c18070b17
1 changed files with 28 additions and 2 deletions
|
|
@ -173,6 +173,33 @@ bool isModifier(uint8_t virtualKey)
|
||||||
return (modifiers.find(virtualKey) != modifiers.end());
|
return (modifiers.find(virtualKey) != modifiers.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AutoTISInputSourceRef copyKeyboardLayoutForKeyTranslation()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(g_tisMutex);
|
||||||
|
|
||||||
|
AutoTISInputSourceRef keyboardLayout(TISCopyCurrentKeyboardLayoutInputSource(), CFRelease);
|
||||||
|
AutoTISInputSourceRef inputSource(TISCopyCurrentKeyboardInputSource(), CFRelease);
|
||||||
|
|
||||||
|
const bool inputSourceHasLayout =
|
||||||
|
inputSource && TISGetInputSourceProperty(inputSource.get(), kTISPropertyUnicodeKeyLayoutData) != nullptr;
|
||||||
|
|
||||||
|
CFBooleanRef isSelectCapable = nullptr;
|
||||||
|
if (keyboardLayout) {
|
||||||
|
isSelectCapable =
|
||||||
|
(CFBooleanRef)TISGetInputSourceProperty(keyboardLayout.get(), kTISPropertyInputSourceIsSelectCapable);
|
||||||
|
}
|
||||||
|
const bool keyboardLayoutIsSelectCapable = isSelectCapable && CFBooleanGetValue(isSelectCapable);
|
||||||
|
|
||||||
|
if (inputSource && keyboardLayout && !inputSourceHasLayout && !keyboardLayoutIsSelectCapable) {
|
||||||
|
AutoTISInputSourceRef asciiKeyboardLayout(TISCopyCurrentASCIICapableKeyboardLayoutInputSource(), CFRelease);
|
||||||
|
if (asciiKeyboardLayout) {
|
||||||
|
return asciiKeyboardLayout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return keyboardLayout;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -293,11 +320,10 @@ KeyButton OSXKeyState::mapKeyFromEvent(KeyIDs &ids, KeyModifierMask *maskOut, CG
|
||||||
}
|
}
|
||||||
|
|
||||||
// get keyboard info
|
// get keyboard info
|
||||||
AutoTISInputSourceRef currentKeyboardLayout(nullptr, CFRelease);
|
AutoTISInputSourceRef currentKeyboardLayout = copyKeyboardLayoutForKeyTranslation();
|
||||||
CFDataRef ref = nullptr;
|
CFDataRef ref = nullptr;
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(g_tisMutex);
|
std::lock_guard<std::mutex> lock(g_tisMutex);
|
||||||
currentKeyboardLayout = AutoTISInputSourceRef(TISCopyCurrentKeyboardLayoutInputSource(), CFRelease);
|
|
||||||
if (currentKeyboardLayout)
|
if (currentKeyboardLayout)
|
||||||
ref = (CFDataRef)TISGetInputSourceProperty(currentKeyboardLayout.get(), kTISPropertyUnicodeKeyLayoutData);
|
ref = (CFDataRef)TISGetInputSourceProperty(currentKeyboardLayout.get(), kTISPropertyUnicodeKeyLayoutData);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue