- SignalDesk1小时前
上一篇发了 LayoutKeeper 之后,有朋友问:恢复窗口位置的工具有好几个,为什么偏偏「连桌面一起恢复」这么难?这篇写写我做这个功能时踩的过程,纯开发日志向。 先说结论:难的不是「移动窗口」,是「知道窗口在哪个桌面」和「让系统允许你把它送回去」。 第一坑:其他桌面的窗口,系统默认不给你看。 辅助功能 API ( AX )只能拿到当前桌面的窗口列表。想枚举外接屏上其他桌面的窗口,得拿公开的窗口列表先算出候选,再用远程元素令牌把窗口找回来,而且要校验进程和窗口编号对得上——校验不过的不动,宁可漏恢复,也不能移错别人的窗口。 第二坑:跨桌面的老接口早就被系统拦了。 以前把窗口挪到另一个 Space 的老办法,从 macOS 14.5 起就被系统拦截,硬调也没用。真正可用的新接口是 macOS 26 才出现的 SkyLight 桥接操作。所以这也是为什么 LayoutKeeper 的跨桌面恢复要求 macOS 26+:不是我不想兼容旧系统,是旧系统上这条路根本不存在。同一桌面内的位置/大小恢复,macOS 14+ 就能用,不受影响。 第三坑:调了接口不等于窗口真的过去了。 私有接口没有文档,返回值也不能全信。我的做法比较笨:每个窗口移动后,回读它实际所在的桌面序号,再回读位置和大小,两次都对上才算成功;对不上的就回滚到移动前,并把这次恢复整体标记为可一键撤销。同名窗口分不清是哪个时(比如开了三个同名文档),直接标「需要确认」让用户选,绝不猜——猜错一次,用户就再也不敢用自动恢复了。 没做到的也说清: - Finder 窗口跨桌面移动不了:身份校验需要进程启动时间,Finder 拿不到,只能跳过(同桌面内调位置没问题)。 - 目前只支持一块外接屏,多屏的桌面归属关系复杂得多,还在想。 - 私有接口依赖系统版本,启动时会自动检测,接口不在就自动关掉跨桌面功能,不会乱移窗口。 好处也有:全程不需要关 SIP 、不需要注入 Dock ,只申请「辅助功能」一个权限——这是我愿意用私有接口的前提,安全性上不能向用户借太多。 项目还是那个:LayoutKeeper ,GPL-3.0 开源,免费。 仓库: https://github.com/tumingke0/LayoutKeeper 做过窗口管理 / Space 相关开发的朋友,欢迎聊聊你们是怎么处理跨桌面窗口枚举的,这块资料实在太少了。
- 情报分类:技术学习与提效
- 分类依据:内容涉及技术、AI、软件工具或工程实践
- 信息来源:服务器 / V2EX
- 发布时间:2026/10/14 16:38:10
- 暂无回复