【开源自荐】Capsense: 用 CapsLock 键切换输入法

与 CapsLox、CapsLock++ 等强大的自定义工具不同,Capsense 只做一件事:用 CapsLock 键来切换输入法,但仍保留切换大写锁定的功能。

https://github.com/alex3236/Capsense/

alex3236/Capsense: Mirror of https://github.com/alex3236/Capsense - Codeberg.org

为什么?

Windows 的输入法一直让人头疼。通常我们用这么几种方式切换输入状态:

  • Win+Space: 在所有输入法中循环
  • Ctrl+Space: 切换中英文键盘布局
  • Shift: 将当前输入法修改为中文/英文状态

当你发现键盘现在只能键入英文,大脑往往需要反应一段时间来确认是输入法不对(按Win+Space)还是中英文状态不对(按Shift)。

尽管有不少输入法状态指示的软件,我也试了很多款,但这么多年仍然无法在一秒内完成“识别状态 - 正确完成切换”的操作。

我也试过只保留其中一种切换方式来避免这个问题,因此我尝试只留中文输入法和Shift一个快捷键,但显然,这在游戏等场景中有严重的兼容性问题。

最终我决定做一个工具解决这个多年的问题,同时同步我在 macOS 上的使用习惯。

这个功能用 AHK 实现很容易,这个工具最初也是用 AHK 做的验证,但由于我平时并不使用 AHK,并且希望更轻一点,最终就用 Rust 写了。

怎么用?

从 Release 下载并双击即可。

默认情况下,从文件资源管理器启动时,Capsense 将使用弹窗显示必要的提示信息,
通过其他方式(例如命令行)启动时则不会弹窗。你可以通过命令行参数来修改这一行为。

建议在输入法设置中禁用 Shift 键切换 IME 状态的功能,以获得最佳体验,因为这可能会让你困惑。

使用 CapsLock 切换键盘布局,使用 Win+Space 切换当前键盘布局的主输入法。

实例管理器

当已有实例正在运行时,从资源管理器启动 Capsense,或使用 --gui 参数运行 Capsense,
会打开 实例管理器。你可以在其中无需命令行即可控制正在运行的实例。

命令行参数

在终端中,你可以使用以下参数:

  • -d, --daemon:在后台启动 Capsense。
  • -s, --stop:停止正在运行的 Capsense 实例。
  • -r, --reload:让正在运行的实例从 config.toml 重新加载配置。
  • -S, --status:检查是否有 Capsense 实例在运行并显示其 PID。
  • --gui:允许 Capsense 显示 GUI 窗口。
  • --headless:阻止 Capsense 显示任何 GUI 窗口。
  • --startup <enable|disable>:启用或禁用开机自启。

首次运行时,Capsense 在同一目录下创建一个 config.toml 文件。可以配置以下内容:

  • tap_threshold_ms:超过这个时间的按压将被视为长按。默认为 300 ms。
  • tap_action:在轻按时执行的动作。支持的动作为:
    • shortcut:触发一个键盘快捷键(由 tap_shortcut 定义)。
    • switch_layout:(默认)轮换输入布局。
  • tap_shortcut:要触发的快捷键(默认为 ["LWIN", "SPACE"])。支持的按键有:
    • LWIN(或 WIN)
    • SPACE
    • LCONTROL(或 CTRL)
    • LSHIFT(或 SHIFT)
    • LMENU(或 ALT)
    • CAPSLOCK
  • layouts:当 tap_action 设置为 switch_layout 时要轮换的一组输入布局 ID。
    • 默认:[0x0804, 0x0409]zh-CNen-GB)。
    • 有关更多布局 ID,请参见微软文档。其他常见的有:
      • 0x0404:繁体中文
      • 0x0411:日文
      • 0x0412:韩文
  • no_en:若启用,Capsense 将防止中文输入法在布局切换或焦点更改后进入英文模式。(默认为 true)。
1 个赞

每个输入法都能指定单独的快捷键
输入法状态指示器这个门类感觉很成熟了, 绝对醒目不会漏看


我只使用单独的快捷键和Shift, 就没有这些麻烦了
中英文输入都是Google拼音3, 其实输入法切换都很少, 打游戏直接用默认英文输入法
虽然有疑问那大小写切换这功能不用了, 但是我貌似也很少用Caplock切换 :upside_down_face:

1 个赞

好东西,我也是习惯MAC上的切换输入法方式,切换快了有延迟可以用以下命令解决

hidutil property --set '{"CapsLockDelayOverride":0}'

另外大家有没有在Mac上远程win时,使用mac键位映射方案?

感谢你的回复,我说一下我本人试过的结果:

  • 键盘布局指示器是非常明显的,但(对我而言)很难形成从看到到切换的肌肉记忆,当中文输入法处于英文状态时仍然要反应一下才能做动作
  • 因为我经常需要中英交替输入,所以追求单键切换,否则效率大降,而ShiftCtrl在游戏中会有兼容性问题,而其他按键(如F区)又不在小拇指(延续之前习惯)的快速反应的区域
  • 事实上我个人体验过最好的办法是脚踏按键,踩着是中文,不踩是英文,但移动办公无法支持这样的操作
  • 最终找了一圈,CapsLock键是最适合做这个工作的,平时用到的地方很少,又离手指足够近。
  • 感谢你的提醒,我注意到之前忘记说明长按切换大写锁定了,已补充

你这玩意让我有个想法。

有种U盘状的hid工具叫做badusb,可以用duckyscript脚本编写指令。如果用作黑客用途的话,那么它应该会通过numlock、capslock闪灯来外传数据,毕竟这两个量键盘是知道的。

但如果指令是双击CapsLock或者双击numlock后自动执行切换输入法的组合键的话,感觉可以写进badusb后直接用硬件实现了,应该在任何电脑上都能使用

好用,mac上最喜欢的就是capslock切输入法,特别不理解还要改成shift的

建议添加–admin参数,自动弹出UAC提升权限界面

另外,GUI设置自启时,只有后台为管理员权限,而GUI以用户权限启动时才提示“从注册表自启动无法控制以管理员权限运行的应用。以管理员身份运行以启用任务计划程序自启动。”,建议改成默认显示或者注册表启用时弹窗提示,默认的用户级/系统级提示不够明确

成功用ahk 实现功能

#Requires AutoHotkey v2.0

; 配置长按的时间阈值,单位为秒 (0.3 秒 = 300 毫秒)

tap_threshold := 0.3

*CapsLock:: {

    ; 等待 CapsLock 键被释放,或者达到超时时间

    ; KeyWait 返回 1 表示在超时前释放(短按),返回 0 表示超时(长按)

    if KeyWait("CapsLock", "T" tap_threshold) {

        ; 【短按】:切换输入法

        ; Windows 默认切换输入法是 Win + Space,所以这里发送 #{Space}

        ; 如果你的切换快捷键是 Ctrl+Shift,请将其改为 Send("^{Shift}")

        ; 如果是 Alt+Shift,请将其改为 Send("!{Shift}")

        Send("#{Space}")

    } else {

        ; 【长按】:触发大小写锁定/解锁

        ; 获取当前 CapsLock 状态并将其反转

        currentState := GetKeyState("CapsLock", "T")

        SetCapsLockState(currentState ? "Off" : "On")

         ; 等待按键真正物理释放,避免长按期间反复触发或闪烁

        KeyWait("CapsLock")

    }

}

我一开始也是用ahk实现的(

#Requires AutoHotkey v2.0

*CapsLock::
{
    if KeyWait("CapsLock", "T0.3") {
        Send("#{Space}") 
    } else {
        ; Long press: Toggle CapsLock state
        state := GetKeyState("CapsLock", "T")
        SetCapsLockState(!state)
        
        ; Wait for the key to be released to prevent repeating
        KeyWait("CapsLock")
    }
}

模拟快捷键的话有多个输入法的时候比较头疼

英雄所见略同,我也是将 CapsLock 映射为切换输入法,哈哈。

不过我更加彻底一些,CapsLock 变成了专属按键,不和其他功能搅在一起。

<SwitchInputMethod>:
    GetKeyState, CapsLockState, CapsLock, T
    SetCapsLockState, AlwaysOff
    Send, ^{space}
return