关联问题
Follow-up:#161。
#161 曾因被认为属于 Windows 多显示器问题而关闭。对当前窗口恢复代码复核后,可以确认应用层仍缺少保存坐标的可见性校验,因此在显示器拓扑变化后能够稳定出现该问题。
已在 #161 补充代码分析;由于无权限重开他人创建的 issue,新建此 issue 跟踪修复。
问题现象
AUTO-MAS 会保存主窗口的位置。如果上次退出时窗口位于副屏,之后断开副屏再启动,主窗口仍可能恢复到旧副屏坐标,导致:
- 任务栏和托盘图标正常出现;
- 主窗口完全不可见;
- 点击任务栏图标也无法把窗口恢复到当前屏幕;
- 部分环境下
Win + Shift + ←/→ 同样无法找回窗口。
复现步骤
- 连接两个显示器。
- 将 AUTO-MAS 主窗口移动到副屏。
- 正常退出应用,保存副屏窗口坐标。
- 断开副屏,只保留主屏。
- 再次启动 AUTO-MAS。
也可以把 config/frontend_config.json 中的 UI.location 设置为远超当前桌面范围的坐标进行验证。
实际结果
窗口使用已失效的旧坐标创建,完全位于所有当前显示器工作区之外。
期望结果
启动时检测保存的窗口 bounds 是否仍与任一显示器工作区有效相交。如果窗口不可操作,应自动移回主显示器可见区域。
根因定位
问题位于 frontend/electron/main.ts 的 createWindow() 及窗口边界更新逻辑:
- 从
config.UI.location 读取 cfgX/cfgY。
screen.getDisplayNearestPoint({ x: cfgX, y: cfgY }) 只用于获取显示器缩放和工作区尺寸。
- 创建
BrowserWindow 时仍原样传入 x: cfgX, y: cfgY,没有约束到目标显示器的 workArea。
recomputeMinSize() 仅修正宽高,不修正 x/y。
- 未监听
screen.on('display-removed') 对现有窗口进行恢复。
因此这不仅是 Windows 自身行为,应用当前确实会恢复未经校验的失效坐标。
修复建议
增加统一的窗口可见性校验函数,在启动恢复和显示器变化时使用:
- 通过
screen.getAllDisplays() 获取所有显示器 workArea。
- 检查待恢复 bounds 是否与至少一个工作区存在足够的有效相交,建议至少保证一段标题栏可见并可拖动。
- 若与所有工作区均无有效相交,则将窗口居中放到
screen.getPrimaryDisplay().workArea。
- 将窗口宽高限制在目标工作区内,并保存修正后的 bounds。
- 监听
display-removed 和 display-metrics-changed,显示器布局变化后重新校验。
- 正确支持位于主屏左侧或上方显示器的合法负坐标,不能简单限制
x/y >= 0。
- 最大化窗口可先修正其 normal bounds,再执行
maximize()。
验收标准
关联问题
Follow-up:#161。
#161 曾因被认为属于 Windows 多显示器问题而关闭。对当前窗口恢复代码复核后,可以确认应用层仍缺少保存坐标的可见性校验,因此在显示器拓扑变化后能够稳定出现该问题。
已在 #161 补充代码分析;由于无权限重开他人创建的 issue,新建此 issue 跟踪修复。
问题现象
AUTO-MAS 会保存主窗口的位置。如果上次退出时窗口位于副屏,之后断开副屏再启动,主窗口仍可能恢复到旧副屏坐标,导致:
Win + Shift + ←/→同样无法找回窗口。复现步骤
也可以把
config/frontend_config.json中的UI.location设置为远超当前桌面范围的坐标进行验证。实际结果
窗口使用已失效的旧坐标创建,完全位于所有当前显示器工作区之外。
期望结果
启动时检测保存的窗口 bounds 是否仍与任一显示器工作区有效相交。如果窗口不可操作,应自动移回主显示器可见区域。
根因定位
问题位于
frontend/electron/main.ts的createWindow()及窗口边界更新逻辑:config.UI.location读取cfgX/cfgY。screen.getDisplayNearestPoint({ x: cfgX, y: cfgY })只用于获取显示器缩放和工作区尺寸。BrowserWindow时仍原样传入x: cfgX, y: cfgY,没有约束到目标显示器的workArea。recomputeMinSize()仅修正宽高,不修正x/y。screen.on('display-removed')对现有窗口进行恢复。因此这不仅是 Windows 自身行为,应用当前确实会恢复未经校验的失效坐标。
修复建议
增加统一的窗口可见性校验函数,在启动恢复和显示器变化时使用:
screen.getAllDisplays()获取所有显示器workArea。screen.getPrimaryDisplay().workArea。display-removed和display-metrics-changed,显示器布局变化后重新校验。x/y >= 0。maximize()。验收标准