长久以来,输入法一直是困扰mac用户的一个问题;不过随着国内厂商的跟进,这种状况得到了极大的改善。不用自己去折腾什么鼠须管了,狼厂和企鹅都做的不错。

不过依然有一个问题没有完全解决:不同程序之间输入的自动切换。

相信大家一定有切换到item2输入两个命令发现是中文然后按cmd + space切换的尴尬;另外如果你如果使用vi或者emacs,那么就更蛋疼了。造成这种状况的根本原因在于:输入法的状态是混乱的,我无法明白现在自己处于哪一种输入环境,除非我开始打字或者看右上角输入法的图标。我希望item2,Intellij IDEA,Alfred2永远是英文输入状态,除非手动切换;其他的程序比如chrome浏览器,邮件客户端保持正常。

打个比方,使用sublime写代码,大多数情况下肯定是英文输入状态,写注释的时候可能手动切换到中文;但是这里有个问题,这时候如果我切换到其他程序,然后改变了输入的状态,再次回到sublime,fuck!怎么又成了中文!

目前解决方案有如下方式:

mac系统自带的设置-> 键盘 -> 输入源 -> 自动使用文稿的输入源

一些输入法的类似安静模式的功能

第一种方式,意思就是不同的程序保持独立的输入状态,不会出现你在另外一个程序切换了输入法的时候再次回来输入法状态就变了。这个开关很有用,我使用了一段时间,发现还是怪怪的,有时候并不符合预期,但是具体场景也搞不明白,反正是一头雾水,有时候依然会陷入困惑的状态。

第二种方式很有意思,应该可以满足很多非程序员的需求。这个安静模式,打个比方,鼠须管输入法;这种输入法其实有几种输入模式,如果对于sublime开启安静模式,那么在进入sublime程序的时候,会自动切换到英文输入模式;nice!不过问题就是:如果要切换到中文模式,需要按ctrl或者shift。如果使用一些IDE的话,肯定各种快捷键用的飞起,怎么少的了按ctrl和shift,这时候问题就来了,如果我们一不小心在使用某些快捷键的时候触发了这个输入法的模式切换功能,那么就蛋疼了:我们需要不停滴按shift切换确保自己处于正确的状态。更糟糕的是,如果你发现自己处于鼠须管的英文输入模式,想使用中文,然后按了cmd + space 切换,你有可能会切换到系统的英文输入法,打个字发现依然是英文!fuck!你不信邪,以为是没有按到,再猛敲几次cmd + space,最后你自己处于那个状态就晕了。

怎么正确配置输入法

经过这些折腾之后,可以得到输入法的这么几条最佳实践:

最基本的原则是要很方便滴知道自己处于哪一种输入状态。如果任何时候清楚这个,那么就是简单的切换问题了。

最好不要使用一个输入的两种模式,并使用shift或者ctrl切换;如上文,某些情况会陷入极度混乱,最好在输入法之间切换,模式简单。

所有程序输入法状态应该有一个恒定的初始态,每次你重新进入这个程序,就会回到初始状态。

为什么需要一个恒定的初始状态呢?为了明确自己处于哪一种输入状态,只需要在每次进入这个程序的时候,不管之前做过什么,它的状态是确定的,姑且叫它初始态;然后基于原则2,每次你希望切换的时候cmd + space一下,需要的时候换回来,如果你去了别的程序再回来,状态重置为初始态。

好了分析了这么多,其实要解决的问题就是3一个,我们写一段小程序。

切换输入法实现

mac下如果使用objc或者swift切换输入法很简单,Apple提供了很详细的Text Input Service文档(现在这个文档403了,可以使用google的cache访问);我希望使用python来调用这些接口,很遗憾的是,pyobjc没有封装TIS系列函数,手动使用ctypes模块来wrap一下:

import ctypes

import ctypes.util

import objc

import CoreFoundation

_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.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)

切换输入法主要是TISSelectInputSource方法,简单滴调用这个方法就可以了。使用ctypes包装这个方法有两个地方可以借鉴:

pyobjc 转ctypes兼容类型

pyobjc提供的对象是不能直接传递给ctypes要包装的函数使用的,需要转换成可以识别的类型。每一个pyobjc提供的对象都有一个__c_void_p__()方法,对它调用这个方法就可以把这个对象转换成一个c_void_p类型

ctypes指针构造出pyobjc对象

简单包装一下objcruntime里面的new方法,然后可以直接根据指针new一个对象出来。正如以上代码的PyObjCObject_New。(新版的pyobjc模块貌似已经包装了这个方法)

PS:本人第一次包装objc接口,对于objc以及pyobjc均不熟悉,可能有更优雅的方法,请批评指正。

如何自动切换?

要想实现输入法自动切换,自然是需要在某程序切换到前台的时候,帮它更改一下输入法的状态;如果知道一个程序是不是在前台呢?最笨的办法当然就是轮询,但是不够优雅。幸运的是,新的mac系统提供了这个回调。

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)

这一段代码可以拿到最前台运行的application,而且是回调通知。有两个地方需要注意:

Observer对象需要先new出来,(我直接在函数参数里面调用,直接就是segement fault,不知道原因)不能使用python的构造对象方式。需要调用new方法。

需要使用AppHelper.runConsoleEventLoop 才能接收到事件,至于为什么见参考。

成果

好了,把上面两段代码整合起来;就能实现每次在打开某些程序的时候,自动切换到某个输入法了!

每次我切换到IDEA敲代码,输入法状态永远都是英文;就算我切换到其他回个邮件,发个消息切换到了中文,再次回来依然是英文;我手动切换到了中文被打断了去做了别的事情,再次回来,依然是英文状态。我永远都知道自己处于什么输入模式,如果不满足条件,cmd + space 切换即可。

最后,你可以使用supervisor之类的东西把它加入开机自动运行,这样,困惑已久的输入法问题终于得到解决。

mac c语言identifier,mac下自动切换输入法相关推荐

  1. 在苹果Mac如何实现自动切换输入法

    AutoSwitchInput ( 自动切换输入法 ) 是一款可以为mac应用指定默认输入法的工具.能够根据当前正在运行的不同的应用程序,自动切换对应的输入法,免去人工手动切换,可设置快捷键,在特定情 ...

  2. Mac电脑的自动切换输入法

    很多情况下,在 Mac系统上切换中英文会很麻烦,无论它是搜狗还是自己输入,切换都很麻烦. 快捷键切换输入方式 自动切换输入法中,快捷键的设置可以让我们快速切换输入法.只要你设置好快捷键之后,不管想要哪 ...

  3. 自动切换输入法 mac版能让你在不同的应用之间自动的切换输入法

    自动切换输入法专业版for mac一款切换输入法辅助工具.自动切换输入法 mac版能让你在不同的应用之间自动的切换输入法,以及中英文.让你的文字输入行云流水,从此告别繁琐的手动切换输入法,大幅提高输入 ...

  4. 自动切换输入法--Mac高效切换输入法工具

    你还在手动切换输入法吗?太慢啦!推荐「自动切换输入法 」Mac版给大家,这是一款简洁的切换输入法辅助工具,能让你在不同的应用之间自动切换输入法,以及中英文,提高打字效率! 功能1.自动切换输入法:支持 ...

  5. Mac电脑快速切换输入法!自动切换输入法!

    Mac电脑一般都会带有不同的输入法,而我们在不同的APP则可能需要不同的输入法来帮我们完成操作或者是工作.那么自动切换输入法就能来帮我们了. 自动切换输入法功能: 1.设置快捷键:自动输入法会有设置快 ...

  6. Mac电脑的一键切换输入法神器,自动切换输入法!

    Mac电脑在输入法的切换上,可谓是有点费时费力了,因为只能上下切换输入法的设置,我们想快速的找到所需要的输入法是有点困难的.这时候小编就在想,有没有可以一键切换输入法的设置或者是快捷键呢,或者自动切换 ...

  7. 在Mac实现自动切换输入法

    自动切换输入法是一款国产的Mac效率神器,并且是免费使用的,使用方法非常简单打开软件之后,点击右上角的图标,给当前打开的 App 设置默认的输入法,然后重启相应 App ,设置就会生效.从此,系统就会 ...

  8. Mac电脑的效率超高的输入法,自动切换输入法

    我们在使用Mac电脑键盘打字时,有时候需要用到不同的输入法,或者是切换中英文输入法.而Mac电脑就有个弊端,只能上下切换输入法.那么有没有什么便利工具可以帮我们解决这个问题呢?这里小编给你分享一个软件 ...

  9. vsftp不允许切换到其它目录_AutoCAD效率革命之四——自动切换输入法

    一.为什么要自动切换输入法 如果你用快捷命令进行作图的话,经常会碰到这种情况,输命令时跳出来中文输入法,又得切换成英文,输文字时又是英文输入法,还得切换成中文. 当这种情况反复出现时,就严重影响作图效 ...

最新文章

  1. 典型相关分析(cca)原理_CCA典型关联分析原理与Python案例
  2. 网络设备监控-Catic添加H3C的监控图解
  3. [python opencv 计算机视觉零基础到实战] 一 opencv的helloworld
  4. JavaApplet 绘制火柴棒和轮播图片
  5. 一种基于红黑树的定时器
  6. C# 中的DevExpress CheckedListBoxControl控件
  7. POJ2155 Matrix 二维线段树
  8. pythonselenium函数_selenium2.0 关于 python 的常用函数汇总
  9. 雷林鹏分享:Lua break 语句
  10. 升级到ASP.NET2.0之后的疑问
  11. OpenCore配置文字说明(第二版)基于056(03-02官方正式版)
  12. 阿里巴巴大数据计算平台MaxCompute全套攻略
  13. 兴达易控Profinet转TCP以太网模块
  14. 手机版wps怎么制作折线图_wps怎么制作目录
  15. Linux双独立显卡SLI,完美的解决方案:双显卡不需要使用双水冷Tt提供SLi冷却解决方案...
  16. python人工智能入门书籍推荐-有哪些关于人工智能的书籍可供推荐?
  17. Hadoop与spark性能比较试验
  18. 使用JIRA管理项目工单
  19. GeoServer结合FWTools切片工具发布影像金字塔切片
  20. 通用的WAN协议配置

热门文章

  1. javascript基础学习 1
  2. 点击地图获取经纬度(基于腾旭地图api)
  3. nefu 1116 字符串加密
  4. Android实例-手机安全卫士(四十一)-选择自定义Toast背景
  5. 实体链接在小布助手和OGraph的实践应用
  6. SMARTBI 电子表格——分片报表
  7. 方管图纸标注_方管尺寸标准
  8. OpenCV C++案例实战二十九《遥感图像分割》
  9. 如何实现移动端点击下拉箭头显示全部文字
  10. 帮你抢小游戏流量红利——360小游戏接入指南