做一个常驻菜单栏的小工具细节比想象中多一个窗口切换工具看上去就是把窗口列出来点一下再切过去。最近做 TaskView除了这个基本流程我花了不少精力处理设置、权限和打包这些事。做出能展示窗口的界面只完成了其中一部分。用户会快速开关会在系统设置里改权限会把新版拖进另一个目录也会希望它登录以后自己启动。这些动作都得有明确的处理结果。设置页要说明操作有没有成功比如快捷键。默认用 ⌥Tab 很方便但别人的电脑可能已经把它分配给其他工具了。设置页需要能录入新组合也得处理注册失败。新组合被占用时保留原来的快捷键并告诉用户修改没有保存。录制组合期间原来的全局快捷键要暂时停用避免用户正在输入新组合任务视图却被弹出来。按 Esc、关闭设置窗口或者窗口失去键盘焦点时也要退出录制状态。开机自启也有类似的问题。勾上一个开关不等于系统一定会让应用在登录后运行。所以设置页直接读取 macOS 登录项的状态区分已经启用、等待批准和没有开启。需要系统批准时给一个入口去处理。其他显示参数就简单一些。悬停选择、背景压暗、清晰度、显示器范围和应用分组保存在偏好里重新打开以后继续使用。把这些选项集中起来比让用户记住几条启动命令更适合日常使用。图真实设置页上半部分。本机快捷键为 ⌘Z自启已开启这些是拍摄时的配置不代表默认值。快速开关时后台工作也得收住还有窗口缩略图。窗口多的时候一次把所有图片抓完会产生不必要的工作。现在只给可见的卡片加载缩略图最多四路并发滚出可见区域的图片会释放引用。后台截图已经发出去的仍要等系统返回快速开关视图也不能因此越积越多。图片返回时也得确认它属于哪一次打开。用户可能已经关闭视图或者换了搜索条件。如果把旧图片填回新的卡片画面和窗口身份就会对不上。筛选、分组和截图回调都要保留原始窗口索引。这属于代码层面的控制。长时间常驻到底占多少 CPU、多少内存还需要实际采样不能只凭“原生应用”几个字就给出结论。目前项目提供了空闲采样脚本但还没有小时级常驻数据。关闭视图时会释放应用持有的窗口和图片数据系统缓冲与内存分配器什么时候归还内存又是另一层问题。描述这部分时代码行为和实测结果需要分开。关闭别人的窗口需要留一点余地窗口卡片上的 ×调用的是目标应用的辅助功能关闭按钮。对于未保存的文档保存、取消这些决定仍然交给原应用。目标窗口的匹配也要谨慎。同一个应用里可能有几个标题相同的窗口搜索以后显示顺序又会改变。关闭操作会结合标题与几何信息寻找唯一匹配结果有歧义时宁可返回失败。发出请求以后先收起任务视图目标应用才能显示确认窗口。界面不能把“请求已经发出”直接说成“窗口已经关闭”两者可能隔着一次用户选择。应用得能说明自己是哪一份最近还补了一个很容易被忽略的地方让应用自己说明正在运行哪一份。设置页显示版本、构建号、构建渠道、构建时间和运行路径。本地开发包与下载包同时放在电脑上时至少能先确认打开的是哪个位置。构建时间保存为 UTC界面转换成中文的本机时间。Beta 发布用版本和构建号共同区分比如同一版本的下一次测试包递增构建号旧的下载附件继续保留。图1.0.0、构建 2 的 Beta 实机信息。运行路径已用不透明色块遮盖其余信息保留原样。签名也需要保持稳定。项目的构建脚本要求证书签名失败时保留旧应用不会自动换成临时签名。发布脚本会核对附件校验值和包内版本签名材料保存在本地不会跟着源码或者 ZIP 上传。还需要继续验证的部分TaskView 目前使用 Swift 和 AppKit窗口信息与缩略图在本机处理没有实现账号、遥测和截图上传。主要操作就是快捷键打开网格搜索或选择窗口再切过去也可以请求关闭指定窗口。当前下载版仍是未经过 Apple 公证的 Beta支持 macOS 14 及以上的 M 系列 Mac需要用户自行授予屏幕录制和辅助功能权限。权限、签名和首次安装这些环节也得继续在不同机器上验证。项目的源码和开发说明都放在仓库里安装包单独放在 Releases。如果也在做 macOS 菜单栏工具可以翻一下相关实现。