diff options
Diffstat (limited to 'platform/osx/display_server_osx.mm')
-rw-r--r-- | platform/osx/display_server_osx.mm | 152 |
1 files changed, 98 insertions, 54 deletions
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index 9a1191490c..4a94e09c1c 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -2987,85 +2987,129 @@ void DisplayServerOSX::cursor_set_custom_image(const RES &p_cursor, CursorShape } } +struct LayoutInfo { + String name; + String code; +}; + +static Vector<LayoutInfo> kbd_layouts; +static int current_layout = 0; static bool keyboard_layout_dirty = true; static void keyboard_layout_changed(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef user_info) { + kbd_layouts.clear(); + current_layout = 0; keyboard_layout_dirty = true; } -// Returns string representation of keys, if they are printable. -static NSString *createStringForKeys(const CGKeyCode *keyCode, int length) { - TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); - if (!currentKeyboard) - return nil; +void _update_keyboard_layouts() { + @autoreleasepool { + TISInputSourceRef cur_source = TISCopyCurrentKeyboardInputSource(); + NSString *cur_name = (NSString *)TISGetInputSourceProperty(cur_source, kTISPropertyLocalizedName); + CFRelease(cur_source); - CFDataRef layoutData = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); - if (!layoutData) - return nil; + // Enum IME layouts + NSDictionary *filter_ime = @{ (NSString *)kTISPropertyInputSourceType : (NSString *)kTISTypeKeyboardInputMode }; + NSArray *list_ime = (NSArray *)TISCreateInputSourceList((CFDictionaryRef)filter_ime, false); + for (NSUInteger i = 0; i < [list_ime count]; i++) { + LayoutInfo ly; + NSString *name = (NSString *)TISGetInputSourceProperty((TISInputSourceRef)[list_ime objectAtIndex:i], kTISPropertyLocalizedName); + ly.name.parse_utf8([name UTF8String]); - const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData); + NSArray *langs = (NSArray *)TISGetInputSourceProperty((TISInputSourceRef)[list_ime objectAtIndex:i], kTISPropertyInputSourceLanguages); + ly.code.parse_utf8([(NSString *)[langs objectAtIndex:0] UTF8String]); + kbd_layouts.push_back(ly); - OSStatus err; - CFMutableStringRef output = CFStringCreateMutable(NULL, 0); + if ([name isEqualToString:cur_name]) { + current_layout = kbd_layouts.size() - 1; + } + } + [list_ime release]; - for (int i = 0; i < length; ++i) { - UInt32 keysDown = 0; - UniChar chars[4]; - UniCharCount realLength; + // Enum plain keyboard layouts + NSDictionary *filter_kbd = @{ (NSString *)kTISPropertyInputSourceType : (NSString *)kTISTypeKeyboardLayout }; + NSArray *list_kbd = (NSArray *)TISCreateInputSourceList((CFDictionaryRef)filter_kbd, false); + for (NSUInteger i = 0; i < [list_kbd count]; i++) { + LayoutInfo ly; + NSString *name = (NSString *)TISGetInputSourceProperty((TISInputSourceRef)[list_kbd objectAtIndex:i], kTISPropertyLocalizedName); + ly.name.parse_utf8([name UTF8String]); - err = UCKeyTranslate(keyboardLayout, - keyCode[i], - kUCKeyActionDisplay, - 0, - LMGetKbdType(), - kUCKeyTranslateNoDeadKeysBit, - &keysDown, - sizeof(chars) / sizeof(chars[0]), - &realLength, - chars); + NSArray *langs = (NSArray *)TISGetInputSourceProperty((TISInputSourceRef)[list_kbd objectAtIndex:i], kTISPropertyInputSourceLanguages); + ly.code.parse_utf8([(NSString *)[langs objectAtIndex:0] UTF8String]); + kbd_layouts.push_back(ly); - if (err != noErr) { - CFRelease(output); - return nil; + if ([name isEqualToString:cur_name]) { + current_layout = kbd_layouts.size() - 1; + } } - - CFStringAppendCharacters(output, chars, 1); + [list_kbd release]; } - return (NSString *)output; + keyboard_layout_dirty = false; } -DisplayServerOSX::LatinKeyboardVariant DisplayServerOSX::get_latin_keyboard_variant() const { - _THREAD_SAFE_METHOD_ - - static LatinKeyboardVariant layout = LATIN_KEYBOARD_QWERTY; +int DisplayServerOSX::keyboard_get_layout_count() const { + if (keyboard_layout_dirty) { + _update_keyboard_layouts(); + } + return kbd_layouts.size(); +} +void DisplayServerOSX::keyboard_set_current_layout(int p_index) { if (keyboard_layout_dirty) { - layout = LATIN_KEYBOARD_QWERTY; + _update_keyboard_layouts(); + } + + ERR_FAIL_INDEX(p_index, kbd_layouts.size()); - CGKeyCode keys[] = { kVK_ANSI_Q, kVK_ANSI_W, kVK_ANSI_E, kVK_ANSI_R, kVK_ANSI_T, kVK_ANSI_Y }; - NSString *test = createStringForKeys(keys, 6); + NSString *cur_name = [NSString stringWithUTF8String:kbd_layouts[p_index].name.utf8().get_data()]; - if ([test isEqualToString:@"qwertz"]) { - layout = LATIN_KEYBOARD_QWERTZ; - } else if ([test isEqualToString:@"azerty"]) { - layout = LATIN_KEYBOARD_AZERTY; - } else if ([test isEqualToString:@"qzerty"]) { - layout = LATIN_KEYBOARD_QZERTY; - } else if ([test isEqualToString:@"',.pyf"]) { - layout = LATIN_KEYBOARD_DVORAK; - } else if ([test isEqualToString:@"xvlcwk"]) { - layout = LATIN_KEYBOARD_NEO; - } else if ([test isEqualToString:@"qwfpgj"]) { - layout = LATIN_KEYBOARD_COLEMAK; + NSDictionary *filter_kbd = @{ (NSString *)kTISPropertyInputSourceType : (NSString *)kTISTypeKeyboardLayout }; + NSArray *list_kbd = (NSArray *)TISCreateInputSourceList((CFDictionaryRef)filter_kbd, false); + for (NSUInteger i = 0; i < [list_kbd count]; i++) { + NSString *name = (NSString *)TISGetInputSourceProperty((TISInputSourceRef)[list_kbd objectAtIndex:i], kTISPropertyLocalizedName); + if ([name isEqualToString:cur_name]) { + TISSelectInputSource((TISInputSourceRef)[list_kbd objectAtIndex:i]); + break; } + } + [list_kbd release]; - [test release]; + NSDictionary *filter_ime = @{ (NSString *)kTISPropertyInputSourceType : (NSString *)kTISTypeKeyboardInputMode }; + NSArray *list_ime = (NSArray *)TISCreateInputSourceList((CFDictionaryRef)filter_ime, false); + for (NSUInteger i = 0; i < [list_ime count]; i++) { + NSString *name = (NSString *)TISGetInputSourceProperty((TISInputSourceRef)[list_ime objectAtIndex:i], kTISPropertyLocalizedName); + if ([name isEqualToString:cur_name]) { + TISSelectInputSource((TISInputSourceRef)[list_ime objectAtIndex:i]); + break; + } + } + [list_ime release]; +} + +int DisplayServerOSX::keyboard_get_current_layout() const { + if (keyboard_layout_dirty) { + _update_keyboard_layouts(); + } - keyboard_layout_dirty = false; - return layout; + return current_layout; +} + +String DisplayServerOSX::keyboard_get_layout_language(int p_index) const { + if (keyboard_layout_dirty) { + _update_keyboard_layouts(); + } + + ERR_FAIL_INDEX_V(p_index, kbd_layouts.size(), ""); + return kbd_layouts[p_index].code; +} + +String DisplayServerOSX::keyboard_get_layout_name(int p_index) const { + if (keyboard_layout_dirty) { + _update_keyboard_layouts(); } - return layout; + ERR_FAIL_INDEX_V(p_index, kbd_layouts.size(), ""); + return kbd_layouts[p_index].name; } void DisplayServerOSX::_push_input(const Ref<InputEvent> &p_event) { |