站立办公久了肩膀酸?把手机放到键盘托架上,扫码秒变 macOS 触控板,纯局域网、零云服务、无需 pip 依赖。
前言
升降桌 + 站立办公成了越来越多程序员的标配,但有一个隐藏痛点很少有人提:手臂长时间悬空去够触控板,斜方肌真的受不了。
本文分享一个开源项目 mouse-control,用 3 行命令把手机变成 Mac 的原生风格触控板。
项目简介
mouse-control 是一个纯局域网方案,通过 WebSocket 把手机浏览器连接到 Mac,手机端触摸事件实时映射为 Mac 光标动作。
核心特性:
- 🖱️ 触控板:单/双击、拖拽、拖拽锁
- 🤏 双指捏合缩放(⌘+/⌘−)
- 🖐️ 三指滑动:切桌面空间、调度中心、App Exposé
- ⌨️ 键盘:实时输入,支持中文 / emoji
- 🎤 语音输入:手机系统听写 + Web Speech API
- 🍎 仿 macOS 视觉:交通灯、毛玻璃、Dock 风格控制条
快速开始
前置:macOS + Node.js ≥ 18 + Homebrew
git clone https://github.com/askxiaozhang/mouse-control.git
cd mouse-control
brew install cliclick
npm install
npm start
终端会打印 Mac 名、局域网 URL、PIN 和二维码,手机相机一扫即可连接。
架构拆解
手机浏览器 (HTML/CSS/JS) ──WebSocket──▶ Node 服务 (Mac)
├─ cliclick → 移动/点击/拖拽/控制键
└─ lib/helper.py (ctypes)→ 滚动 / Unicode 文本 / 快捷键
为什么有两个后端?
cliclick 5.1 有三处不足:
- 没有
scroll命令 t:不能输入中文(无 key code)kp:不支持字符键组合(如⌘+)
因此滚动、Unicode 文本输入、修饰键快捷键都用纯标准库 ctypes 调 CoreGraphics 的 CGEvent 实现——无需 pip 安装任何依赖。
高频合并策略
触摸移动是 60Hz 事件,逐条 spawn cliclick 必卡。控制器把增量累积,"单进程在飞"合并 flush,所有 cliclick 调用串行化,按执行速度自然限频,延迟有界。
CGEvent 文本输入
CGEventKeyboardSetUnicodeString 直接投递 Unicode 串(按 ≤20 码元分块),支持中文 / emoji,绕过 cliclick t: 的 key code 限制。
手势速查
| 手势 | 动作 |
|---|---|
| 一指移动 | 移动光标 |
| 一指轻点 | 单击 |
| 连续两次轻点 | 双击 |
| 一指按住后移动 | 拖拽 |
| 双指轻点 | 右键 |
| 双指移动 | 滚动 |
| 双指张开/捏合 | 放大/缩小 |
| 三指左右滑 | 切换桌面空间 |
| 三指上滑 | 调度中心 |
| 三指下滑 | App Exposé |
鉴权与安全
- WebSocket 必须 PIN 鉴权后才接受控制指令
- PIN 在二维码 URL 里以
?pin=明文带出便于扫码 - 仅用于可信局域网,不建议暴露公网
使用建议
- 第一次使用需给终端开"辅助功能"权限(一次性)
- 手机和 Mac 必须在同一 Wi-Fi
- 双指滚动方向可在手机设置里切换"自然滚动"
小结
这个项目的价值不只是"又一个遥控器 App",而是一个思路:把输入设备放到低处,让手臂自然下垂——这个姿势的改变,可能比升降桌本身更影响你的使用体验。
项目开源,MIT 协议,欢迎 Star / Issue / PR: