[ISSUE-0057] watchdog 自动恢复触发浏览器确认关闭弹窗¶
用户截图(v0.10.76): - 浏览器弹"您即将关闭 2 个标签页。确定要继续吗?" - 同时扩展通知"健康巡检:自动恢复中(第 1/9999 次)" 用户诉求:仅关 tab 不关窗口 → 不要触发浏览器确认弹窗
根因¶
src/utils/scrape-window.ts:124 forceCloseSharedWindow():
Chrome / Cent Browser 的 confirmBeforeWindowClose 设置("关闭多 tab 窗口时确认")对 chrome.windows.remove(id) 生效。
window 里有 ≥ 2 个 tab(采集页 + 翻页/sorry/...)→ 浏览器弹"确认关闭 N 个标签页"。
Watchdog 每次"健康巡检自动恢复"都调 forceCloseSharedWindow() → 每次都打断用户。
maybeCloseSharedWindow() 也走同款 windows.remove,理论上 active=0 时还可能有 2+ 占位 tab(about:blank)→ 同款风险。
修¶
用 tabs.remove(tabIds) 列表式关 tab —— Chrome confirmBeforeWindowClose 对 tabs.remove 不触发。
关完所有 tab 后 Chrome 自动关空 window,也不弹确认。
const tabs = await browser.tabs.query({ windowId: id });
const tabIds = tabs.map((t) => t.id).filter((tid): tid is number => tid != null);
if (tabIds.length > 0) {
await browser.tabs.remove(tabIds);
} else {
await browser.windows.remove(id); // 空 window 兜底
}
两个 close path 都改:
- forceCloseSharedWindow (line 124) — watchdog 自动恢复用
- maybeCloseSharedWindow (line 80) — 正常 close 路径
为什么 tabs.remove 不触发确认¶
Chrome 设计:confirmBeforeWindowClose 是"用户主动关一整个含多 tab 窗口"的保护。tabs.remove 是"扩展程序逐 tab 关闭" — 系统视为"扩展知道自己在做什么",不打扰。
最后一个 tab 关掉后 window 自动关 — 不算"关窗口",所以不弹。
audit_grep¶
- pattern: "browser\\.windows\\.remove\\([^)]"
description: "windows.remove 触发浏览器确认弹窗 — 优先用 tabs.remove(tabIds) 列表式"
未来如再有人 browser.windows.remove → pre-commit 警告 → 改 tabs.remove。
注意点¶
tabs.remove([])空数组无作用,需 fallback 到windows.removetabs.remove(allTabIds)是 Promise.all 风格批量,比 for-loop 快- ext-context-guard 的 forceClose 链路不受影响(它走的不是 sharedWindow)
相关¶
- [[0027-watchdog-resume-settimeout-bug|0027-watchdog自动恢复setTimeout同款Bug]] — watchdog 历史 issue
- 修bug全字典扫描 — 两个 close path 全字典扫