using TISSelectInputSource

Hello again,

I would like to change the input source (keyboard layout) from within my AOSC script. I found TISSelectInputSource as possible option in http://macscripter.net/viewtopic.php?id=26894 but my first attempt in translating this to ASOC failed miserably.

set inputSource to “German”
current application’s TISSelectInputSource_(inputSource)

As usual I would appreciate any help to get this working in ASOC.

Thanks,
Dirk

Hallo Dirk,

so einfach ist das nicht.
(it’s not that easy)

The bad news is, TISSelectInputSource is a C function which cannot be exposed to AppleScriptObjC.
But even if it was possible, inputSource is not a string it’s a C reference type.

In C / Objective-C the code to be able to change the language is something like this


      NSArray  *inputArray = (NSArray *)TISCreateInputSourceList ( NULL, false);
      NSMutableDictionary *availableLanguages = [NSMutableDictionary dictionaryWithCapacity:[inputArray count]];
      NSUInteger i;
      for (i = 0; i < [inputArray count]; ++i) {
        [availableLanguages setObject:inputArray[i] forKey:TISGetInputSourceProperty((TISInputSourceRef)inputArray[i], kTISPropertyLocalizedName)];
      }
      TISInputSourceRef newLanguage = (TISInputSourceRef)[availableLanguages objectForKey:@"German"];
      OSStatus err = TISSelectInputSource (newLanguage);


it gets all available languages and puts them into a Dictionary with their localized names as keys. Then it grabs the German source reference and sets the language.

However this code is usable in AppleScriptObjC with a bridge class

Hi Stefan,

I was afraid that you would say that, otherwise some search engine would have returned more hints.

Would you mind explaining how I can use this code in a bridge class. That topic is still way too much above my head to even google it.

Thanks,
Dirk

¢ In Xcode create a new OS X Cocoa Class, Language Objective-C Subclass of NSObject and name it InputSwitcher
¢ Replace the contents of InputSwitcher.h with

[code]@import Foundation;

@interface InputSwitcher : NSObject

  • (BOOL)setLanguage:(NSString *)language;

@end[/code]
¢ Replace the contents of InputSwitcher.m with

[code]#import “InputSwitcher.h”
@import Carbon;

@implementation InputSwitcher

  • (BOOL)setLanguage:(NSString *)language
    {
    NSArray *inputArray = (__bridge NSArray *)TISCreateInputSourceList ( NULL, false);
    NSMutableDictionary *availableLanguages = [NSMutableDictionary dictionaryWithCapacity:[inputArray count]];
    NSUInteger i;
    for (i = 0; i < [inputArray count]; ++i) {
    [availableLanguages setObject:inputArray[i] forKey:(__bridge id)(TISGetInputSourceProperty((__bridge TISInputSourceRef)inputArray[i], kTISPropertyLocalizedName))];
    }
    TISInputSourceRef newLanguage = (__bridge TISInputSourceRef)[availableLanguages objectForKey];
    if (newLanguage) {
    OSStatus err = TISSelectInputSource (newLanguage);
    return err == noErr;
    }
    return NO;
    }

@end[/code]
If you get error and warning messages you have to add the Carbon Framework in Target > Build Phases > Link Binary With Libraries

¢ In the AppleScriptObjC script add a property

property InputSwitcher : class "InputSwitcher"

and switch the language with

set success to InputSwitcher's setLanguage:"German"

success is 1 on success or 0

You are the man! Did exactly that and it works like a dream.

Tausend Dank,
Dirk