[Mono-dev] Text Input Source Services

Chris Hubbard chris_hubbard at sil.org
Tue Feb 17 18:40:25 UTC 2015


Hello,

I would like to access Text Input Source Services from a mono app.  I would like to get the id, localized name, and primary language of all the currently configured keyboard input sources.  I also want to change the selected keyboard input source during my application depending on which field is being typed in (it is an app that manages lexicon information and we want to change the keyboard depending on the writing system of the field being typed in).

Text Input Source Services lives in the Carbon.framework but is not a "Carbon" API.

Here is the Objective-C code that I would like to write in C#:

    const void *keys[] = { kTISPropertyInputSourceCategory };
    const void *values[] = { kTISCategoryKeyboardInputSource };
    CFDictionaryRef filter = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, NULL, NULL);
    
    NSArray *sources = CFBridgingRelease(TISCreateInputSourceList(filter, FALSE));
    for (NSUInteger i = 0; i < sources.count; ++i) {
        TISInputSourceRef source = (__bridge TISInputSourceRef)sources[i];
        NSString *Id = (__bridge NSString *)TISGetInputSourceProperty(source, kTISPropertyInputSourceID);
        NSString *LocalizedName = (__bridge NSString *)TISGetInputSourceProperty(source, kTISPropertyLocalizedName);
        NSArray *Languages = CFBridgingRelease(TISGetInputSourceProperty(source, kTISPropertyInputSourceLanguages));
        NSString *primaryLanguage = NULL;
        if ([Languages count] > 0) {
            primaryLanguage = [Languages objectAtIndex:0];
        }
        
	// Do something with these properties in C# code
        NSLog(@"Id=%@, LocalizeName=%@, Primary Language=%@", Id, LocalizedName, primaryLanguage);
    }
    
    CFRelease(filter);

The challenge I saw with this is exposing constants (from TextInputSources.h). For example:

extern const CFStringRef kTISPropertyInputSourceCategory;

Are there any examples of this?  I don’t know how the API implementation is doing comparisons (pointer value or string comparisons--and it could change over time).

Another options is to use the Cocoa API NSTextInputContext (from monomac/src/appkit.cs): 

               [Static]
                [Export ("localizedNameForInputSource:")]
                string LocalizedNameForInputSource (string inputSourceIdentifier);

                [Export ("keyboardInputSources")]
                NSArray /* NSString [] */ KeyboardInputSources { get; }

                [Export ("selectedKeyboardInputSource")]
                string SelectedKeyboardInputSource { get; set; }

The first one (LocalizedNameForInputSource) already exists.  I added the last two in a local build and they worked correctly.  They only thing missing from the Cocoa API is getting the primary language of a keyboard input source based on the input source identifier.

So my questions are:
1) What is the proper way to expose Text Input Source Services to Mono code?
2) OR Is there a Cocoa way to get the language of a Keyboard Input Source? 
3) OR should a create a Objective-C Library that wraps Text Input Source Services and make a interop for that library?

Thanks,

Chris Hubbard


More information about the Mono-devel-list mailing list