Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
auto switch keyboard to english in specific applications
#! /usr/bin/env python
# coding: utf-8
'''
auto switch keyboard between different applications
if you want to change the app list, modify the var 'ignore_list'
'''
from AppKit import NSWorkspace, NSWorkspaceDidActivateApplicationNotification, NSWorkspaceApplicationKey
from Foundation import NSObject
from PyObjCTools import AppHelper
import ctypes
import ctypes.util
import objc
import CoreFoundation
# add your custom apps here, check the bundle id in /Application/xx.app/Contents/info.plist
ignore_list = [
"com.googlecode.iterm2",
"com.runningwithcrayons.Alfred-2",
"com.jetbrains.intellij.ce-EAP"
]
carbon = ctypes.cdll.LoadLibrary(ctypes.util.find_library('Carbon'))
_objc = ctypes.PyDLL(objc._objc.__file__)
# PyObject *PyObjCObject_New(id objc_object, int flags, int retain)
_objc.PyObjCObject_New.restype = ctypes.py_object
_objc.PyObjCObject_New.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_int]
def objc_object(id):
return _objc.PyObjCObject_New(id, 0, 1)
# kTISPropertyLocalizedName
kTISPropertyUnicodeKeyLayoutData_p = ctypes.c_void_p.in_dll(carbon, 'kTISPropertyInputSourceIsEnabled')
kTISPropertyInputSourceLanguages_p = ctypes.c_void_p.in_dll(carbon, 'kTISPropertyInputSourceLanguages')
kTISPropertyInputSourceType_p = ctypes.c_void_p.in_dll(carbon, 'kTISPropertyInputSourceType')
kTISPropertyLocalizedName_p = ctypes.c_void_p.in_dll(carbon, 'kTISPropertyLocalizedName')
# kTISPropertyInputSourceLanguages_p = ctypes.c_void_p.in_dll(carbon, 'kTISPropertyInputSourceLanguages')
kTISPropertyInputSourceCategory = objc_object(ctypes.c_void_p.in_dll(carbon, 'kTISPropertyInputSourceCategory'))
kTISCategoryKeyboardInputSource = objc_object(ctypes.c_void_p.in_dll(carbon, 'kTISCategoryKeyboardInputSource'))
# TISCreateInputSourceList
carbon.TISCreateInputSourceList.restype = ctypes.c_void_p
carbon.TISCreateInputSourceList.argtypes = [ctypes.c_void_p, ctypes.c_bool]
carbon.TISSelectInputSource.restype = ctypes.c_void_p
carbon.TISSelectInputSource.argtypes = [ctypes.c_void_p]
carbon.TISGetInputSourceProperty.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
carbon.TISGetInputSourceProperty.restype = ctypes.c_void_p
# carbon.TISCopyCurrentKeyboardLayoutInputSource.argtypes = []
# carbon.TISCopyCurrentKeyboardLayoutInputSource.restype = ctypes.c_void_p
carbon.TISCopyInputSourceForLanguage.argtypes = [ctypes.c_void_p]
carbon.TISCopyInputSourceForLanguage.restype = ctypes.c_void_p
def get_avaliable_languages():
single_langs = filter(lambda x: x.count() == 1, \
map(lambda x: objc_object(carbon.TISGetInputSourceProperty(CoreFoundation.CFArrayGetValueAtIndex(objc_object(s), x).__c_void_p__(), kTISPropertyInputSourceLanguages_p)), \
range(CoreFoundation.CFArrayGetCount(objc_object(carbon.TISCreateInputSourceList(None, 0))))))
res = set()
map(lambda y: res.add(y[0]), single_langs)
return res
def select_kb(lang):
cur = carbon.TISCopyInputSourceForLanguage(CoreFoundation.CFSTR(lang).__c_void_p__())
carbon.TISSelectInputSource(cur)
class Observer(NSObject):
def handle_(self, noti):
info = noti.userInfo().objectForKey_(NSWorkspaceApplicationKey)
bundleIdentifier = info.bundleIdentifier()
if bundleIdentifier in ignore_list:
print "found: %s active" % bundleIdentifier
select_kb(u'en')
def main():
nc = NSWorkspace.sharedWorkspace().notificationCenter()
observer = Observer.new()
nc.addObserver_selector_name_object_(
observer,
"handle:",
NSWorkspaceDidActivateApplicationNotification,
None
)
AppHelper.runConsoleEventLoop(installInterrupt=True)
main()
@johnwatsondev

This comment has been minimized.

Copy link

commented Jun 1, 2016

It will be great if can change the custom input source rather than by language type. Because of that, I have a custom input source layout.

Eg: I want to change to U.S.custom input source.
2016-06-01 17 29 43

@XiYeLv

This comment has been minimized.

Copy link

commented Jul 26, 2017

厉害了……

@wangxujie

This comment has been minimized.

Copy link

commented Aug 18, 2018

如果是安装搜狗输入法, select_kb(u'en'),这个会切换到默认输入法的英文输入。怎么能切到搜狗的英文输入
感谢

@too

This comment has been minimized.

Copy link

commented Mar 22, 2019

直接跑起来似乎可用啊,不错!

@frankqiu0219

This comment has been minimized.

Copy link

commented May 26, 2019

如果是安装搜狗输入法, select_kb(u'en'),这个会切换到默认输入法的英文输入。怎么能切到搜狗的英文输入
感谢

我也想问这个问题

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.