|
@@ -1437,8 +1437,18 @@ void OS_OSX::initialize_core() {
|
|
|
SemaphoreOSX::make_default();
|
|
|
}
|
|
|
|
|
|
+struct LayoutInfo {
|
|
|
+ String name;
|
|
|
+ String code;
|
|
|
+};
|
|
|
+
|
|
|
+static Vector<LayoutInfo> kbd_layouts;
|
|
|
+static int current_layout = 0;
|
|
|
static bool keyboard_layout_dirty = true;
|
|
|
+static OS::LatinKeyboardVariant latin_variant = OS::LATIN_KEYBOARD_QWERTY;
|
|
|
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;
|
|
|
}
|
|
|
|
|
@@ -2787,38 +2797,146 @@ static NSString *createStringForKeys(const CGKeyCode *keyCode, int length) {
|
|
|
return (NSString *)output;
|
|
|
}
|
|
|
|
|
|
+void _update_keyboard_layouts() {
|
|
|
+ @autoreleasepool {
|
|
|
+ TISInputSourceRef cur_source = TISCopyCurrentKeyboardInputSource();
|
|
|
+ NSString *cur_name = (NSString *)TISGetInputSourceProperty(cur_source, kTISPropertyLocalizedName);
|
|
|
+ CFRelease(cur_source);
|
|
|
+
|
|
|
+ // 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]);
|
|
|
+
|
|
|
+ NSArray *langs = (NSArray *)TISGetInputSourceProperty((TISInputSourceRef)[list_ime objectAtIndex:i], kTISPropertyInputSourceLanguages);
|
|
|
+ ly.code.parse_utf8([(NSString *)[langs objectAtIndex:0] UTF8String]);
|
|
|
+ kbd_layouts.push_back(ly);
|
|
|
+
|
|
|
+ if ([name isEqualToString:cur_name]) {
|
|
|
+ current_layout = kbd_layouts.size() - 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ [list_ime release];
|
|
|
+
|
|
|
+ // 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]);
|
|
|
+
|
|
|
+ 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 ([name isEqualToString:cur_name]) {
|
|
|
+ current_layout = kbd_layouts.size() - 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ [list_kbd release];
|
|
|
+ }
|
|
|
+
|
|
|
+ // Update latin variant
|
|
|
+ latin_variant = OS::LATIN_KEYBOARD_QWERTY;
|
|
|
+
|
|
|
+ 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);
|
|
|
+
|
|
|
+ if ([test isEqualToString:@"qwertz"]) {
|
|
|
+ latin_variant = OS::LATIN_KEYBOARD_QWERTZ;
|
|
|
+ } else if ([test isEqualToString:@"azerty"]) {
|
|
|
+ latin_variant = OS::LATIN_KEYBOARD_AZERTY;
|
|
|
+ } else if ([test isEqualToString:@"qzerty"]) {
|
|
|
+ latin_variant = OS::LATIN_KEYBOARD_QZERTY;
|
|
|
+ } else if ([test isEqualToString:@"',.pyf"]) {
|
|
|
+ latin_variant = OS::LATIN_KEYBOARD_DVORAK;
|
|
|
+ } else if ([test isEqualToString:@"xvlcwk"]) {
|
|
|
+ latin_variant = OS::LATIN_KEYBOARD_NEO;
|
|
|
+ } else if ([test isEqualToString:@"qwfpgj"]) {
|
|
|
+ latin_variant = OS::LATIN_KEYBOARD_COLEMAK;
|
|
|
+ }
|
|
|
+
|
|
|
+ [test release];
|
|
|
+
|
|
|
+ keyboard_layout_dirty = false;
|
|
|
+}
|
|
|
+
|
|
|
OS::LatinKeyboardVariant OS_OSX::get_latin_keyboard_variant() const {
|
|
|
|
|
|
- static LatinKeyboardVariant layout = LATIN_KEYBOARD_QWERTY;
|
|
|
+ if (keyboard_layout_dirty) {
|
|
|
+ _update_keyboard_layouts();
|
|
|
+ }
|
|
|
+
|
|
|
+ return latin_variant;
|
|
|
+}
|
|
|
+
|
|
|
+int OS_OSX::keyboard_get_layout_count() const {
|
|
|
+ if (keyboard_layout_dirty) {
|
|
|
+ _update_keyboard_layouts();
|
|
|
+ }
|
|
|
+ return kbd_layouts.size();
|
|
|
+}
|
|
|
|
|
|
+void OS_OSX::keyboard_set_current_layout(int p_index) {
|
|
|
if (keyboard_layout_dirty) {
|
|
|
+ _update_keyboard_layouts();
|
|
|
+ }
|
|
|
+
|
|
|
+ ERR_FAIL_INDEX(p_index, kbd_layouts.size());
|
|
|
+
|
|
|
+ NSString *cur_name = [NSString stringWithUTF8String:kbd_layouts[p_index].name.utf8().get_data()];
|
|
|
|
|
|
- layout = LATIN_KEYBOARD_QWERTY;
|
|
|
-
|
|
|
- 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);
|
|
|
-
|
|
|
- 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];
|
|
|
+}
|
|
|
|
|
|
- keyboard_layout_dirty = false;
|
|
|
- return layout;
|
|
|
+int OS_OSX::keyboard_get_current_layout() const {
|
|
|
+ if (keyboard_layout_dirty) {
|
|
|
+ _update_keyboard_layouts();
|
|
|
+ }
|
|
|
+
|
|
|
+ return current_layout;
|
|
|
+}
|
|
|
+
|
|
|
+String OS_OSX::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 OS_OSX::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 OS_OSX::process_events() {
|