为了省下 0.5 秒,我大概花掉了 50 个小时:Mouse4 开发复盘

0. 这种“过度工程”值得吗?

如果用 ROI(投资回报率)来计算,Mouse4 绝对是一个失败的项目。

为了省去把鼠标移到左上角点“返回”的那 0.5 秒,或者为了省去登录微信才能截图的麻烦,我前后迭代了 55 个版本,重写了三次渲染核心,甚至为了修一个 Bug 去翻了 Windows 的底层 API 文档。

但这就是程序员(或者说极客)的宿命:我们无法忍受工具的“钝感”。

Mouse4 的诞生,不是为了做一个通用的软件,而是为了打造一个完全契合我个人生理习惯的“数字义肢”

1. 第一层:肌肉记忆的延伸

最早的 Mouse4 其实不叫 Mouse4,它只是一段几 KB 的 Python 脚本。

作为一个需要高频浏览财报和文件的基金经理/老师,Windows 资源管理器的交互逻辑让我抓狂:为什么“进入文件夹”是双击,而“返回上一级”却要大幅度移动鼠标去点那个该死的箭头?

我的需求很原始: 我希望我的鼠标在哪里,哪里就是控制台。

于是,我利用 UIAutomation 做了一个简单的钩子:当且仅当鼠标停留在文件夹的空白处双击时,模拟按下 Backspace

这个功能上线后,我几乎忘记了它的存在。这才是工具的最高境界——隐形。它变成了我肌肉记忆的一部分,以至于我在别人的电脑上操作时,总会下意识地双击空白处,然后看着毫无反应的屏幕发愣。

2. 第二层:与“物理像素”的战争

如果说“双击返回”是顺手,那“截图”功能的开发就是一场与 Windows 缩放机制的恶战

作为一个多屏重度用户(左竖屏看盘,中横屏工作,右屏摸鱼),我的桌面环境简直是开发者的噩梦:

  • 显示器 1:4K 分辨率,200% 缩放。

  • 显示器 2:4K 分辨率,150% 缩放。

  • 显示器 3:1080P 分辨率,100% 缩放。

当我试图把截图功能加上去时,Python 的 GUI 库(PyQt)彻底晕了。 在 4K 屏上截图,画面要么被暴力拉伸成马赛克,要么截取的区域和鼠标选中的区域完全错位。最夸张的一次,我在中间屏幕画了一个圆,结果鼠标松开时,那个圆出现在了右边的屏幕上。

这背后的技术鸿沟在于: 操作系统为了照顾旧软件,会把 4K 屏“谎报”成 1080P(逻辑像素)。而截图软件需要的是“真·4K”(物理像素)。

这就导致了“坐标系打架”:

  • 鼠标说:“我在坐标 (500, 500)。”

  • 屏幕说:“好的,但在我这里,那是物理像素 (1000, 1000)。”

  • 截图引擎说:“啊?那我到底该切哪块图?”

在 V48 到 V54 的几十次崩溃中,我最终放弃了依赖框架的自动缩放。我写了一套手动映射算法,强行接管了所有坐标计算。现在的 Mouse4,是在像素级别上“手动”把逻辑坐标对齐回了物理坐标。

这种严丝合缝的快感,只有在 200% 缩放的屏幕上拖出一个像素都不差的选区时,才能体会得到。

3. 第三层:来自 Excel 的“幽灵”

就在我以为大功告成时,一个足以逼疯开发者的 Bug 出现了。

有一天,我正在 Excel 里输入数据 712,屏幕突然一黑,截图界面弹了出来。 我的快捷键是 Ctrl+1。但我发誓,我当时绝对没有按 Ctrl

这简直是玄学。 难道我的键盘漏电了?

经过排查,罪魁祸首竟然是**“手速太快”。 我在输入数字前,习惯性地用了 Ctrl+C 复制数据。当我快速切换窗口并敲击键盘时,Windows 的消息队列有时候会“跟不上”,导致 Python 的监听库没听到** Ctrl 键弹起的那一声信号。

于是,在程序的认知里,Ctrl 键一直是被按住的(幽灵状态)。此时我只要按个 1,程序就判定:Ctrl + 1 触发!

为了杀掉这个幽灵,我被迫降维打击: 在 V55 版本中,我引入了 C++ 时代的古老兵器 —— GetAsyncKeyState。 现在,每当你按下快捷键,Mouse4 不会轻易相信,而是会直接质问操作系统底层:“现在的物理键盘上,Ctrl 键到底有没有通电?”

只有物理层面的确认,才能打败逻辑层面的延迟。从此,那个幽灵消失了。

4. 尾声:工具的温度

回顾这几十个小时的折腾,原本只是想把两个小功能缝合在一起,最后却变成了一场涉及底层钩子、高分屏渲染算法、多线程并发的技术练兵。

现在的 Mouse4,界面依然简陋,没有任何多余的动画。 但当我每天几百次地双击空白处返回,或者在 4K 屏上极其顺滑地截下一张图时,这种完全受控、绝对精准的感觉,让我觉得这一切“无用功”都是值得的。

这可能就是我们折腾工具的意义: 在这个充满不确定性的世界上,至少手中的鼠标和代码,永远忠诚于你。


This article was updated on 一月 21, 2026

Share It JohnWish1590 © 2026 约翰祈祷1590 · 独立开发者

© 2026 约翰祈祷1590 · 独立开发者