ImageForge 1.3.1:一个窗口,一个队列
两个平台上同样的现象——把多张图片交给应用,它却空空如也地打开——背后其实是两个毫不相干的原因。下面分别讲讲。
两个平台上同样的现象——把多张图片交给应用,它却空空如也地打开——背后其实是两个毫不相干的原因。下面分别讲讲。
一条用户反馈,两个操作系统,两个毫无共同点的根因。在 Mac 上,把四张图片拖到 Dock 图标会开出四个窗口,而这批文件只进了其中一个。在 Windows 上,“用 ImageForge 打开”无论交给它多少文件,应用都会以空列表打开。1.3.1 把两个都修好了——而它们各自是怎么坏的,值得讲一讲。
把四张图片拖到 Dock 图标上,就会冒出四个窗口,每个都有自己的空列表,争着接收这批文件。原因不在我们的代码:主窗口当时是 SwiftUI 的 WindowGroup,而当 macOS 投递打开文稿的 Apple Event 时,WindowGroup 会为每个文稿各开一个窗口。系统日志毫不含糊:一个携带四个文件的事件,紧接着创建了四个窗口——全都发生在我们的代码看到任何一个路径之前。这批文件进了其中一个窗口,而哪个窗口跑到最前面并不受我们控制,所以应用常常看起来像是空着打开的,再试一次也只是多出几个空窗口。
修复的办法不是用防御性代码把问题围起来,而是把这个应用本来的样子声明出来:一个窗口,一个队列。现在场景用的是 SwiftUI 的 Window,单一实例,Apple Event 或别的什么都无法把它复制出第二个。出于同样的原因,“文件”菜单里的“新建窗口”也移除了:如果关闭了窗口,可以通过“窗口”▸“ImageForge 窗口”(⌘0)、点按 Dock 图标或菜单栏图标重新打开。
Windows 版从第一个版本起就声明了文件类型关联,所以 Windows 会提供“用 ImageForge 打开”,也接受把文件拖到它的图标上。只是它从来没读过这些文件:WinUI 把所有激活都汇集到一个启动方法里,而我们的那个只是创建窗口,把参数扔掉了。关联形同虚设——不管你交给它一张图还是二十张,应用都会以空列表打开。
修的过程中,还推翻了我们的一个想当然。对于打包的桌面应用,Windows 的外壳并不会把一次多选作为一个激活交过来:它会为每个文件各启动一个进程,每个进程的命令行上只有一个路径。四张图片就是四个进程。所以修复分成两半:从命令行读取路径,并选出一个主进程,其余进程在退出前把自己的文件交给它。结果就是本该如此的样子——不管你选多少个文件,都是一个窗口、一个队列。
这两个 bug 都长在应用与操作系统的交界处——单元测试覆盖不到的那一块,因为想知道系统究竟会怎么做,只能看着它做一遍。两个都是靠读系统日志找到的,而不是靠推敲代码;而且两次,代码都在严格执行我们告诉它的事。1.3.1 已在 Mac App Store 和 Microsoft Store 上线;一如既往,一切都在你的设备上完成,绝不上传任何内容。
在 Mac App Store 和 Microsoft Store 免费下载——两边用的是同一个本地引擎。1.3.1 现已上线。