Mac:使用大写锁定键切换输入法

Mac:使用大写锁定键切换输入法

动机

大写锁定键是我的键盘上用的最少的键之一。说是之一,一是因为我的键盘上还有一个关机键使用频率和它有的一拼,二是由于其地理位置优越经常会被误按。

实际上,在Chromebook上,大写锁定键就被Google换成了更为常用的“搜索键”;另外,也有vimer把大写锁定键用作ESC键,效果拔群。

根据个人习惯,我最终决定将大写锁定键更改为输入法切换键,一是因为作为一个中国人输入法切换是使用最多的一个快捷键之一;另一个原因是因为如此一来键上的指示灯还可作为输入法指示灯,简直完美。

更改键绑定

  • 打开系统偏好设置-键盘-键盘-修饰键,将Caps Lock键设为“无操作”
  • 下载Seil(良心软件,良心作者),打开后将Caps Lock键映射为Key Code 80(或者其他一个不存在的键,80代表F19
  • 打开系统偏好设置-键盘-快捷键-输入源,将切换输入法的快捷键设置为F19(通过选择后按一下Caps Lock)

Done! 但是现在问题来了:大写锁定的灯永远不亮,这不优美!我们希望指示灯也更改为能够指示输入法状态,即在英文状态下不亮,在拼音/五笔等输入法状态下亮。经过Google发现,OS X提供了控制键盘灯的底层API,可以手动控制其状态,详见MacLight。这就好办了,于是我依次尝试了以下几种解决方案:

  • 写一段Shell脚本来切换输入法(通过Applescript模拟Keystroke)+切换指示灯状态,通过Automator新建一个“服务”然后将大写锁定键绑定为运行该脚本。但是经过测试发现延时太大(~200ms),放弃。
  • 用Objective-C写一个调用底层API的程序来切换输入法(通过TISSelectInputSource系列API)+切换指示灯状态,发现调用API切换输入法后需要切换到下一个输入窗口才会生效,并且延时依然很大,放弃。
  • 用Objective-C写一个后台应用,通过NSDistributedNotificationCenter接收输入法变更事件,根据状态改变指示灯。科学!

最终采用了最后这种科学的方法。当然,这个后台应用只需要是命令行应用就可以了,通过launchctl等方式开机自动启动即可。不过由于强迫症什么的(方便启动、退出,方便加为登录启动项)还是写成了占领在状态栏的应用,并取名为IMLight,如下图:

下载链接:点我 or Fork me at GitHub

Update for macOS Sierra

升级macOS Sierra后,Seil无法正常使用了(IMLight不影响),详见Github上的这个issue,并且由于是系统接口的大改动,一时半会儿可能不会有修复更新。

Issue中也有人提到,可以使用作者正在开发的另一个针对Sierra的项目Karabiner-Elements,但是这个项目对我来说有几个问题:

  • 与IMLight冲突(虽然不一定是他的问题,但是我暂时也不知道怎么修复…)
  • 会使得系统偏好设置中的针对多个键盘的修饰键设置失效(比如无法把外接键盘的alt和cmd互换),作者表示无法修复

另外的解决方案是在系统偏好设置中把Caps Lock设置为Ctrl(或者其他),然后用其他软件重映射,比如Keyboard Maestro(更改Caps Lock这件事情比较底层,需要内核级别的修改,而监听Ctrl等键这件事情就很简单了)。我使用免费的hammerspoon来实现:

local M = {}

local events = hs.eventtap.event.types
M.log = hs.logger.new(‘caps_remap‘, ‘info‘)

M.last_flags_1 = {}
M.last_flags_0 = {}
M.last_time_1 = 0
M.last_time_0 = 0

M.timeout = 0.15
M.key = "ctrl"
M.action = function() hs.eventtap.keyStroke({}, "f19") end

local function _dict_has_no_other_key(dic)
    for k,v in pairs(dic) do
        if k ~= M.key then
            return false
        end
    end
    return true
end

function M.event_callback(e)
    local typ = e:getType()
    local code = e:getKeyCode()
    local flags = e:getFlags()
    local now = hs.timer.secondsSinceEpoch()

    if _dict_has_no_other_key(flags) and not flags[M.key]
        and _dict_has_no_other_key(M.last_flags_0) and M.last_flags_0[M.key]
        and _dict_has_no_other_key(M.last_flags_1) and not M.last_flags_1[M.key]
        and now - M.last_time_0 < M.timeout
        then
        M.log.i("Fire caps action")
        if M.action then
            M.action()
        end
    end

    M.last_flags_1 = M.last_flags_0
    M.last_flags_0 = flags

    M.last_time_1 = M.last_time_0
    M.last_time_0 = now

    return false
end

function M.init(options)
    if options.key then
        M.key = options.key
    end
    if options.timeout then
        M.timeout = options.timeout
    end
    if options.action then
        M.action = options.action
    end
    M.watcher = hs.eventtap.new({events.flagsChanged}, M.event_callback)
    M.watcher:start()
end

return M

即快速按一下ctrl(即Caps Lock)会触发F19,而其他包含ctrl的组合键并不会,可以满足要求。

时间: 2024-11-03 22:42:21

Mac:使用大写锁定键切换输入法的相关文章

惠普笔记本按开机键后电源灯亮的,但是屏幕一直是黑的,只有大写锁定键闪烁,闪3次一个循环,听得到风扇

现象: 惠普笔记本按开机键后电源灯亮的,但是屏幕一直是黑的,只有大写锁定键闪烁,闪3次一个循环,听得到风扇转动的声音,热风,cpu应该也在工作,请问是什么问题. 解决(我按照红色的作了,就可以了,真是奇怪...): 您好,感谢您选择惠普产品. 1.您的笔记本开机黑屏,请您回忆一下最近是否进行过什么方面特殊操作,比如最近是否进行过硬件改动(例如添加过新内存)或者连接了外接设备,如果是,建议您恢复之前硬件配置及断开所有外接设备看是否可以正常开机. 2.如果您没有进行过特殊操作,使用电池或电源适配器供

js实现判断大写锁定是否开启(转)

转载地址:http://www.cnblogs.com/xiaoao808/archive/2008/07/31/1257624.html 在用户登录输入密码时,常常会有因为大写锁定开启而造成输入密码错误的情况,如果在用户大写锁定开启时给予提示,就可以尽量避免这种情况的发生. 一下是代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/x

教你一招:Win10切换输入法与Win7一样(Ctrl + 空格)

对于win10的朋友,大部分人对输入法都不习惯,如果你把英语输入法删除了,在中文输入法里没有美式键盘,让ctrl+空格与ctrl+Shift都能在搜狗输入法和美式键盘切换.下面小编就教你怎么让Win10切换输入法与Win7一样(Ctrl + 空格). 设置步骤: 1.先安装第三方输入法 比如搜狗输入法. 2.进入语言设置 鼠标右键开始菜单——选择控制面板——时钟.语言和区域模块选择添加语言——把美式键盘删掉,保留简体中文(没有就添加语言,找到简体中文). 3.进入高级设置 4.替代默认输入法 替

JQuery:在input中只能输入数字,并且不能复制粘贴,不能切换输入法(转自纯粹的郭子)

CODE(text in IE6,IE9, Mac,Google Crome): $(function(){                                            $("#<%=txtItem.ClientID %>").keydown(function(e){ // 注意此处不要用keypress方法,否则不能禁用 Ctrl+V 与 Ctrl+V,具体原因请自行查找keyPress与keyDown区分,十分重要,请细查 if ($.brow

js实现密码输入框对开启键盘大写锁定的提示(IE浏览器下有自动识别提示则不执行(用IE自带效果即可))

代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>大写键盘锁定提示</title> </head> <body> 请输入密码:<input class="text" id="loginPasswd" type="password"/> &l

获取系统当前的输入法列表并通过编程方式切换输入法

1.获取输入法列表 //保存输入法信息的结构     struct _tagInputMethod     {      char szLanguageId[30];      char szLanguageName[100];      char szLanguageImeFileName[100];      HICON hIcon;     }; _tagInputMethod m_InputMethodList[30];     int m_InputMethodCount; //获取输

解决Qt5 Creator无法切换输入法(fcitx),Ubuntu中不能使用搜狗输入法录入汉字问题

在Qt5.3之前,我发布过解决办法 解决Qt5 Creator无法切换输入法(fcitx),不能录入汉字问题,Qt5.4以及Qt5.5,旧办法失效,原因是Qt5.4后对之前Qt5版本不再二进制兼容,libfcitxplatforminputcontextplugin.so 需要编译最新的fcitx-qt5,看fcitx-qt5是在1.0.3版本时解决的这个问题,写本篇博客时,我git clone到的是1.0.4版本. 编译fcitx-qt需要cmake,安装cmake命令,如果已经安装,请略过.

解决Qt5 Creator无法切换输入法(fcitx),不能录入汉字问题

笔者系统环境,Ubuntu 14.04,输入法fcitx下搜狗输入法. 其它非Ubuntu linux发行版,不通过软件源安装Qt5,从Qt官网http://qt-project.org/下载安装包,也存在这个问题. 在Ubuntu下解决方法如下,其它linux发行版解决方法雷同 1.安装fcitx for Qt5动态库 sudo apt-get install fcitx-libs-qt5 注:这一个命令执行完毕后,系统中已经具备基于Qt5的程序的汉字录入环境支持.存在一个奇怪现象是,Qt5所

Xamarin开发IOS笔记:切换输入法时输入框被遮住

在进行IOS开发的过程中,出现类似微信朋友圈的交互界面,当用户遇到感兴趣的内容可以进行评论.为了方便评论输入,当出现评论输入框的时候自动将评论输入框移动至键盘的上方,这样方便边输入边查看. 当用户隐藏键盘或者切换输入法的时候需要对输入框位置进行变化,这里需要设定键盘监听方法. 效果如下图: 具体实现方法可以参考Xamarin提供的示例,源代码示例见: https://github.com/xamarin/monotouch-samples/blob/master/BubbleCell/Bubbl