关于 diagnose-hid-keycodes
diagnose-hid-keycodes 是一项 macOS 技能,用于查明未知宏键盘、鼠标按键、脚踏开关等 HID 设备实际发出的键码。它通过 Karabiner-EventViewer 和窗口捕获检查事件,而非依赖标签或厂商文档。
主要功能
- 01识别设备 VID/PID
- 02用 Karabiner-EventViewer 捕获原始按键事件
- 03不切换焦点查看事件
- 04映射不同固件模式的键码
- 05检查 Karabiner 是否接管设备
适用场景
- 01映射新购 HID 键盘的按键
- 02诊断未触发的 Karabiner 规则
- 03记录设备不同模式的键码
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ terrylica/ cc-skills --skill diagnose-hid-keycodes安装后在 Claude Code 中输入/diagnose-hid-keycodes确认已加载。
附带文件CLAUDE.mdreferences/diagnostic-workflow.md
详细介绍
诊断 HID 键码
自我进化技能:此技能会在使用过程中不断改进。如果说明有误、参数发生偏移,或需要采用变通方法,请立即修复此文件,不要拖延。仅针对真实、可复现的问题进行更新。
遇到未知的宏键盘、鼠标按键、脚踏板或 HID 设备时,查明每个按钮在操作系统层面实际发出的内容——不要根据标签、厂商文档或照片猜测。廉价 HID 键盘经常会使用随意分配或标注错误的键码(Jieli/Free3-P 出厂时,标注为上/中/下的按钮分别会发出 Ctrl+C/Ctrl+V/Ctrl+X——这并不符合剪切/复制/粘贴的常规顺序;这些键码是硬件随机分配的)。
何时使用此技能
- 新收到一个 HID 设备,但不知道它的按钮会发出什么
- 键盘有多种固件模式,需要映射每种模式下的键码
- 某条规则没有触发,你怀疑自己猜错了
from.key_code - 需要为设备编写文档,以便复现设置
三工具工作流
| 工具 | 用途 |
|---|---|
Karabiner ignore: true | 让 Karabiner 观察设备,而不接管设备 |
| Karabiner-EventViewer | 以文本形式显示原始 HID 事件 |
Quartz screencapture -l | 捕获 EventViewer 窗口,而不抢占焦点 |
关键在于 ignore: true:启用后,Karabiner 不会重新映射任何内容,但仍会记录设备的事件,因此你可以查看固件发出的原始键码。
工作流
步骤 1 — 确认设备的 VID/PID
# USB
ioreg -p IOUSB -l -w 0 | grep -B 2 -A 6 "<product name or partial>"
# Bluetooth (after pairing)
system_profiler SPBluetoothDataType | grep -A 15 "<pad name>"
以十进制记录 VID/PID(Karabiner 的 JSON 格式)。
步骤 2 — 添加无操作诊断规则(强制 Karabiner 接管设备)
为什么不能只在 devices[] 中设置 "ignore": true? 这会让 Karabiner 完全不处理此设备,EventViewer 也就无法看到它发出的事件。ignore: true 的含义是“不要碰此设备”,而不是“检查此设备”。
正确做法:添加一条限定到此设备的惰性 complex_modifications 规则。Karabiner 会接管设备(这样 EventViewer 就能捕获每份 HID 报告),但规则不会执行任何操作。编辑 ~/.config/karabiner/karabiner.json → 配置文件 0 → complex_modifications.rules,并插入:
{
"description": "[DIAGNOSTIC] Grab <pad> (no remap)",
"manipulators": [
{
"type": "basic",
"from": { "key_code": "vk_none" },
"to": [{ "key_code": "vk_none" }],
"conditions": [
{
"type": "device_if",
"identifiers": [{ "vendor_id": 19530, "product_id": 16725 }]
}
]
}
]
}
vk_none 是 Karabiner 的虚拟按键,永远不会匹配真实输入,因此该操控器不会执行任何操作。device_if 限定范围后,Karabiner 会接管设备以供检查。
重新加载 Karabiner:点击菜单栏中的 Karabiner-Elements 图标 → Restart Karabiner-Elements。
步骤 3 — 打开 EventViewer 并逐个按下按钮
open -a "Karabiner-EventViewer"
- Main 选项卡:显示带解码键码名称(
c、left_control、page_up等)的key_down/key_up - Devices 选项卡:显示发出各个事件的设备,确认你接管的是正确的 VID/PID
- Unknown Events 选项卡:显示 Karabiner 无法解码的事件;这与消费类按键或自定义 HID 描述符有关
缓慢按下每个按钮。对于在同一份 HID 报告中发出的修饰键组合(廉价键盘中很常见),你会看到多个 key_down 事件接连出现:
13:44:02.123 key_down left_control
13:44:02.123 key_down c
13:44:02.198 key_up c
13:44:02.198 key_up left_control
left_control 和 c 的时间戳相同(精确到微秒),表示它们是在同一份 HID 报告中发出的 → 你需要使用 simultaneous 匹配器。
步骤 4 — 捕获画面而不抢占焦点
如果将 EventViewer 切换到前台来查看,就无法再按下测试窗口中的按钮。变通方法是按窗口 ID 捕获:
# List windows; find EventViewer's window ID
python3 -c '
from Quartz import CGWindowListCopyWindowInfo, kCGWindowListOptionAll, kCGNullWindowID
for w in CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID):
if "EventViewer" in w.get("kCGWindowOwnerName", "") or "EventViewer" in w.get("kCGWindowName", ""):
print(w["kCGWindowNumber"], w.get("kCGWindowName"))
'
# Screenshot that window without focusing it
screencapture -l <WID> -o -x /tmp/eventviewer.png
-l <WID> 捕获指定窗口,-o 排除阴影,-x 禁止播放捕获提示音。窗口无需置于前台。
步骤 5 — 对每种固件模式重复操作(蓝牙键盘)
许多廉价蓝牙键盘都有未公开的固件模式,可通过组合按键触发(同时按住 3 个键 5 秒、按住顶部按键 10 秒等)。每种模式发出的按键代码可能完全不同。对于发现的每种模式:
- 将键盘切换到该模式
- 重复步骤 3 — 记录每个按键对应的按键代码
- 在表格中记录
示例(Jieli/Free3-P):
| 模式 | 顶部 | 中间 | 底部 |
|---|---|---|---|
| 1 | volume_increment | volume_decrement | spacebar(播放/暂停) |
| 4 | page_up | page_down | equal_sign |
步骤 6 — 清理
从 complex_modifications.rules 中移除 [DIAGNOSTIC] 规则,然后重新加载 Karabiner。也可以将其转换为实际的重映射规则:用实际的 from / to 绑定替换 vk_none。
避免触发 Touch ID 的审计
在此工作流中,不要查询 /Library/Application Support/com.apple.TCC/ 下的 TCC.db 或 SQLite 文件来“审计权限”——此类查询需要 sudo,而且每次执行都会触发 Touch ID 提示。请改用:
# Non-sudo audit: is Karabiner actually grabbing the device?
karabiner_cli --list-connected-devices | jq '.[] | select(.product == "<pad-name>")'
# Returns { ..., "is_grabbed": true/false } — same info, no biometric prompt
正在使用的工具本身就是审计工具。这是吃了亏才发现的;参见 ../configure-macro-keyboard/references/04-anti-patterns.md →“基于 Sudo 的 TCC.db 审计会触发 Touch ID”。
深入参考
../configure-macro-keyboard/references/03-patterns.md— 完整介绍 "ignore: truediagnostic" 和 "Quartz window-ID capture" 模式../configure-macro-keyboard/references/04-anti-patterns.md— 顶层的{"any": "key_code"}会静默失败;位置推断错误./references/diagnostic-workflow.md— 附带截图的扩展分步说明
相关技能
configure-macro-keyboard— 确认按键发出的内容后,使用此技能编写限定设备的 Karabiner 规则。将此处步骤 2 中的vk_none空操作规则替换为from/to绑定,即可直接转换为实际规则。emit-fn-key-on-macos— 如果发现的某个按键代码应重映射为真正的 Fn 键(用于 Typeless、听写、地球键),此相关技能会介绍唯一正确的 Karabiner 写法。
执行后反思
此技能执行完毕后,请在结束任务前进行反思:
- 确认位置。 — 在进行任何编辑前,确认此 SKILL.md 是权威文件。
- 哪里失败了? — 修复导致失败的说明。
- 哪些效果超出预期? — 将其列为推荐实践。
- 哪些内容出现偏差? — 如果实际情况与文档不符,请更新供应商 ID、按键代码或 FOSS 工具版本。
- 记录下来。 — 添加一条演进日志(或在
04-anti-patterns.md中添加一行),注明触发条件、修复方法和证据。
不要推迟处理。下一次调用会继承你留下的一切。