给你的键盘一百种灵魂 · 打字即禅
一个极简的 macOS 机械键盘音效 App — 在任何 App 里敲任何键,都能出真实机械键盘的声音。18 款真实录音 · 23 MB 原生 · 不带 Electron。
这是 Mechvibes 在 macOS 上的精神续作 — 同样的音色库,但用 Tauri 2 + Rust 原生重写,零 Electron 开销。
到 Releases 页面,下载最新的 纸上键-v*.dmg(Apple Silicon,macOS 11+)。
打开 DMG,把「纸上键」拖到 /Applications/。
⚠️ 本 App 使用 ad-hoc 签名,没经过 Apple 公证。双击会被 Gatekeeper 拦。
正确姿势:在 /Applications/ 里找到「纸上键」,右键 → 打开,弹窗里再点「打开」。之后就可以双击了。
跟着 App 里的三步引导走:
欢迎 → 解释权限用途 → 点「去开启」(会弹系统授权对话框)
然后在系统设置 → 隐私与安全性 → 输入监控 里打开「纸上键」开关,回到 App,敲键盘 → 出声 🎵。
为什么要这个权限?macOS 对「全局捕获键盘事件」的 App 要求 Input Monitoring(输入监控) 权限,跟截屏录屏同级。 App 只监听「哪个键被按下」这个信号,不读取键的内容,也不联网。
ad-hoc 签名的代码哈希(CDHash)每次更新都会变,老的权限记录会失效。App 会自动检测并在状态栏提示,点一下会打开修复面板,按步骤把「纸上键」从列表删掉再拖回来即可。
详见 INSTALL.md 的「权限失效怎么办」章节。
不适合:
cargo build --target x86_64-apple-darwin| 问题 | 解决 |
|---|---|
| 双击打不开 / 显示「来自身份不明的开发者」 | 右键 → 打开 |
| 按键没声音 | 看状态栏提示;或点「诊断」看是不是 Input Monitoring 没开 |
| 更新后权限失效 | 点状态栏「⚠ 权限失效」→ 按引导修复 |
| 声音太吵 / 太小 | App 内音量条可调 |
| 想换音色 | 点任意一张卡片切换,选择会被记住 |
| 想加自己的音色 | 见下面「添加新音色」 |
更多排错:INSTALL.md
# 1. 拉音色(首次必跑,从 mechvibes 上游克隆 18 款音色包到 src/assets/sounds/)
bash scripts/fetch-sounds.sh
# 2. 装依赖
npm install
rustup target add aarch64-apple-darwin # M 系列 Mac
# 3. 开发模式
npm run tauri dev -- --target aarch64-apple-darwin
# 4. 一键打包(build + ad-hoc 签名 + 自定义 DMG)
bash scripts/release.sh 0.2.0
# 产物:dist/纸上键-v0.2.0.dmg(约 23 MB,含 /Applications 拖拽符号链接)
paper-key/
├── src/ # 前端(原生 HTML + JS,无框架)
│ ├── index.html # 18 张音色卡 + 状态栏
│ ├── app.js # 音色加载 + Web Audio 播放 + Tauri event 桥
│ ├── onboarding.js # 三步引导 + 权限状态 + 诊断面板
│ ├── onboarding.css
│ ├── style.css # 宣纸风 UI
│ └── assets/sounds/ # 18 款音色包(fetch-sounds.sh 拉)
├── src-tauri/
│ └── src/lib.rs # CGEventTap 全局监听 + IOHID 权限 + 诊断命令
├── scripts/
│ ├── fetch-sounds.sh # 拉音色
│ └── release.sh # 一键打包
└── INSTALL.md # 给 beta 用户的安装/排错指南
src/assets/sounds/<id>/ 放 config.json + 音频文件(格式见 mechvibes 文档)src/index.html 里复制一张 .card 加上 data-pack="<id>"rdev 是 Rust 社区最成熟的跨平台键盘监听库,最初用的就是它。但在 macOS 14+ 上会崩:它的 callback 线程里调 TSMGetInputSourceProperty,触发 dispatch_assert_queue_fail → SIGTRAP(macOS 14+ 对 queue assertion 收得更紧)。
最终放弃,直接用 core-graphics 的 CGEventTap + ListenOnly mode 自己写,约 150 行 Rust。
历史上 Mac 键盘音效类 App 基本都要「辅助功能(Accessibility)」权限,那个权限太重(可以模拟点击、修改其他 App 的状态),给全局键盘监听有点用力过猛。
macOS 10.15+ 引入了更细粒度的 Input Monitoring 权限,专门管「只读监听键盘事件」这件事。本 App 走这个权限,更符合最小权限原则。
代码里通过 IOHID API(IOHIDCheckAccess / IOHIDRequestAccess)检测和申请,不走 CGEventTap 的 prompt(那个会强制要 Accessibility)。
| 用途 | 库 | 作者 |
|---|---|---|
| 桌面 App 框架 | Tauri 2 | tauri-apps |
| macOS FFI | core-foundation-rs | Mozilla / Servo |
| CGEventTap 绑定 | core-graphics | Mozilla / Servo |
| JSON | serde | dtolnay et al. |
本项目是站在巨人的肩膀上拼起来的。强烈建议先去给下面这些项目点个 Star。
hainguyents13/mechvibes by Hai Nguyen — 本项目所有 18 款音色包直接来自 mechvibes 仓库,config.json 格式(defines 字段、sprite 偏移)也完全沿用。mechvibes 是 Electron 版本,跨平台支持 Windows / macOS / Linux。
如果你不在 Mac 上,或者想要上游的完整生态(键盘音效商店、自定义音色分享等),请直接用 mechvibes。
mechvibes/src/audio/Claude Code(Anthropic 的 CLI 编码工具)深度参与了这个项目的开发 — 从权限模型调研、CGEventTap 排错到 onboarding UI,都是人机协作的产物。
纸上键完全免费开源。欢迎:
GPL-3.0-or-later — 因为引用了 mechvibes 的音色资产(GPL-3.0),本项目保持一致授权。
LICENSE / NOTICE / 版权声明,不得移除