Overlook,一个跟着手指走的 Mac 主屏
用 Mission Control 的手势,Overlook 会打开一个跟着手指走的主屏,每个窗口都从真实位置飞到属于它的位置。从浏览器转到 Swift 和 AppKit,有几件事让我意外。
我把三根手指放在触控板上往上推,就像要打开 Mission Control。出来的是盖在 Mac 上面的一个主屏,跟着我的手指一点点展开,每个窗口从它真实所在的位置飞到主屏里属于它的位置。这就是 Overlook,我用 Swift 和 AppKit 做的一个 app。我是写网页出身的,所以这一路有不少东西,是在浏览器里从来没轮到我操心的。
上推,停住,滑过去
每次打开,主屏会把所有窗口排成居中的几行,在放得下的前提下尽量放大,顺序始终不变。右边是一列小组件、智能体和便签。背景是我自己的壁纸,嵌在一块带黑色边框的圆角屏幕里,像老款 Mac 那种圆鼓鼓的显像管。窗口都是活的:视频继续播,终端继续输出。
要跳到某个窗口,我就三指上推,不抬手停住,指尖会有一下触感反馈,这时主屏自己把剩下的部分展开。我朝那个窗口滑过去,抬手,人就已经在里面了。
没想到的事
手势在 Dock 看到之前就被截走了。macOS 会把这次上滑变成一个私有事件,而会话级的 event tap 最先看到它,并把它消费掉。一次真实的上滑结束时,进度是 0.21,速度是 4.9,所以我是按速度而不是按距离来确认这个手势的。
然后是幽灵窗口:系统列出来的 37 个「窗口」里,有 26 个根本不是真窗口,只是自动填充面板、权限弹窗,还有早就关掉的窗口。真窗口都属于某个 Space,这些不属于,所以我用 CGSCopySpacesForWindows 把它们筛掉。
还有文字。一张代码卡片滑动时,每一帧要花 550 毫秒,因为视图一动,TextKit 2 就会重新排一遍文字。现在文字改用 TextKit 1。squircle 遮罩也是类似的故事:它每一帧都在变,逼着系统做一整屏的离屏渲染,第 95 百分位的帧耗时到了 44 毫秒。现在边框是盖在上面的一个固定形状,只有它的透明度在变。打开和关闭现在每帧 8.33 毫秒,是实打实的 120 Hz,不掉帧。
我撤掉的,和还没验证的
我在 10 月 26 日撤掉了一个桌面模式。它会把真实窗口挪到各自的缩略图位置,再把其余窗口收到角落里,结果很不直观:窗口凭空消失,位置也变来变去。
另外有些部分,我是在没法完整测试的情况下写的。用持续手势选窗口、从主屏里整理窗口,这两样我都没办法从外部合成系统级的触摸或上滑,只能把手势轨迹写进日志,之后靠真实使用来校准。再加上这个 app 只做了 ad-hoc 签名,每次新构建都要重新授权辅助功能和屏幕录制。
目前就是这样。仓库是私有的。