Work Buddy 遥控器
> 2026-08-01
这是什么
把小米蓝牙遥控器 2 Pro 接到 macOS 上,让它变成控制 WorkBuddy 的实体遥控器。语音输入、切 app、调音量,都不用走回桌前。
为什么做这个
WorkBuddy 用着用着,语音输入的次数越来越多。写代码、记灵感、和 AI 聊天,全靠嘴。但每次都要坐到桌前、点鼠标、按键。这个流程有摩擦。
想做到的事很简单:躺在沙发上也能把活干了。
家里刚好有个吃灰的小米遥控器,嫁接到 WorkBuddy 上。三个最常用的功能:
语音输入。 按一下,WorkBuddy 开始听你说。
功能切换。 12 个按键可以随便映射。微信、Cursor、Claude、Slack,想按哪个按哪个。
音量控制。 直接调系统音量,看视频不用碰键盘。
怎么做到的
四层:
[硬件] 小米遥控器 2 Pro(蓝牙 HID)
↓ IOHIDManager
[Swift] HIDRemoteMonitor
↓ send(action)
[核心] KeyboardInjector(三路兜底)
↓
[系统] macOS / Target App
核心在 KeyboardInjector。每按一个键,它会走三条路:先 CGEvent 模拟键盘,挂了就降级到 NSAppleScript,再挂就用 osascript 子进程。任何一路通就行。
技术上的几个原则:
- 能复用 macOS 原生的就不自己造。
CGEvent.post模拟键盘、NSAppleScript调用系统能力,全是系统给的路。 - 系统怎么想,就怎么做。macOS 切换器要 Cmd 物理键持续按住才能保持显示,那就老老实实按住,别想着绕过。
- 每个功能做三路兜底。主路径挂了就降级,再挂就再降级,加日志。
三个印象深的坑
电源键打开 WorkBuddy 直接黑屏
按电源键,WorkBuddy 启动,屏幕一黑。再按一下才亮。
原因是 WorkBuddy 是 Electron 写的,启动时有个 splash 窗口,里面是黑的。我之前代码里写了「0.4 秒后强制 activate」,把这个黑窗口拉到了前台。
修法:直接把强制 activate 删了。WorkBuddy 是普通的 main app,启动完会自己跳前台。
显示桌面三种路径都失败
这个功能折腾了好几轮。
第一种方法用 AppleEvent 给 Dock 发事件。Sonoma 之后,ad-hoc 签名的 app 没 entitlement,事件被静默吞了。
第二种方法用 NSAppleScript in-process 调用。需要本 app 自己的 Automation 权限,主公没授权过。
第三种方法用 osascript subprocess。走的是 osascript 自己的权限,不再依赖本 app 的签名。成了。
期间顺便发现主公机器的 symbolichotkeys 里 hotkey 36(F11 → Show Desktop)根本不存在,只有 hotkey 164(⌘F3 → Show Desktop)有绑定。所以必须模拟 ⌘F3。
Command-Tab 切换器选不了程序
第一次做这个功能的时候,以为是「按下 Cmd+Tab,切换器出现,然后方向键选 app」。实现时每次按方向键发一个 Tab 键,带 cmd modifier。
结果:切换器闪一下就消失。
为啥?macOS 切换器要的是 Cmd 物理键持续按住,不是 cmd modifier flag。我代码里把 Cmd 当修饰符传给 keyEvent,系统收到 Tab down(带 cmd flag)+ 50ms 后 Tab up(带 cmd flag),认为 Cmd 没持续按住,切换器就走了。
现在的修法:改用 keyCode 55(左 Cmd)持续按住。第一次按菜单键发 Cmd down,方向键再发 Tab down/up(Cmd 仍在 held 状态)。Enter / Esc / 同键再按发 Cmd up,提交选择。
按键映射
| 按键 | 默认动作 |
|---|---|
| 电源键 | 打开 WorkBuddy |
| OK 键 | Return |
| 方向键 × 4 | 方向键 |
| 菜单键 | Command-Tab |
| 主页键 | 显示桌面 |
| 返回键 | Delete |
| 音量 +/− | 系统音量 |
| TV 键 | 打开微信 |
除了默认动作,还能映射成 Return / Enter / Escape / Delete / 方向键 / 显示桌面 / 上下文菜单 / Command-Tab / 自定义快捷键 / 13 个 app 启动。
实际使用
沙发上看视频:音量键调音量,菜单键切 app,主页键回桌面。
客户演示:电源键启动 WorkBuddy,TV 键切微信对话,不用走回桌前。
编程时:双手不离键盘,遥控器调音量、切音乐、切 Slack。
培训直播:镜头前不用到处走。
最后
5378 行 Swift、19 个文件。macOS 13 到 15 都能用。
参考
- 设计参考:Pentagram 编辑设计、瑞士国际主义(Müller-Brockmann / Hofmann)、Kenya Hara 克制留白、Fathom 数据叙事
- macOS API:IOHIDManager、CGEvent、NSAppleScript、NSWorkspace、osascript subprocess、
com.apple.symbolichotkeysAppleSymbolicHotKeys、TCC Automation
布拿拿科技 · 2026-08-01