fix: 恢复窗口/标签关闭时的未保存数据检查

恢复 onBeforeUnload 功能,防止关闭窗口或标签时丢失未保存的数据:
  - 快捷键关闭:检查当前激活标签的 onBeforeUnload
  - 点击窗口关闭按钮:依次检查所有标签,遇到拦截时激活对应标签
  - 点击 tab 关闭按钮:检查对应标签的 onBeforeUnload
  - 重构 close 事件处理,使用 early return 简化代码结构
This commit is contained in:
kuaifan 2026-01-13 14:49:59 +00:00
parent f8f08c9d0d
commit 067a736b57

View File

@ -497,19 +497,54 @@ function createWebTabWindowInstance(windowId, position, mode = 'tab') {
})
webTabWindow.on('close', event => {
if (webTabClosedByShortcut.get(windowId)) {
const isShortcut = webTabClosedByShortcut.get(windowId)
if (isShortcut) {
webTabClosedByShortcut.set(windowId, false)
if (!isWillQuitApp()) {
closeWebTabInWindow(windowId, 0)
event.preventDefault()
return
}
}
// 只有 tab 模式才保存 bounds
const windowData = webTabWindows.get(windowId)
if (windowData && windowData.mode !== 'window') {
if (!windowData) return
// 只有 tab 模式才保存 bounds
if (windowData.mode !== 'window') {
userConf?.set('webTabWindow', webTabWindow.getBounds())
}
// 应用退出时不检查
if (isWillQuitApp()) return
// 检查页面是否有未保存数据
if (isShortcut) {
// 快捷键关闭:只检查当前激活的标签
const activeTab = windowData.views.find(v => v.id === windowData.activeTabId)
if (!activeTab) return
const proxyWindow = Object.create(webTabWindow, {
webContents: { get: () => activeTab.view.webContents }
})
utils.onBeforeUnload(event, proxyWindow).then(() => {
closeWebTabInWindow(windowId, 0)
})
return
}
// 点击窗口关闭按钮:依次检查并关闭每个标签页
const checkAndCloseTabs = async () => {
// 复制标签列表,因为关闭时会修改原数组
const tabs = [...windowData.views]
for (const tab of tabs) {
// 先激活要检查的标签,让用户看到是哪个标签有未保存数据
activateWebTabInWindow(windowId, tab.id)
const proxyWindow = Object.create(webTabWindow, {
webContents: { get: () => tab.view.webContents }
})
// 检查并等待用户确认(用户取消则 Promise 不 resolve中断循环
await utils.onBeforeUnload(event, proxyWindow)
// 确认后关闭这个标签(最后一个标签关闭时窗口会自动销毁)
closeWebTabInWindow(windowId, tab.id)
}
}
checkAndCloseTabs()
})
webTabWindow.on('closed', () => {
@ -1563,6 +1598,20 @@ function registerIPC() {
windowId = findWindowIdByTabId(tabId)
}
if (windowId) {
const windowData = webTabWindows.get(windowId)
if (windowData) {
const tab = windowData.views.find(v => v.id === tabId)
if (tab) {
const proxyWindow = Object.create(windowData.window, {
webContents: { get: () => tab.view.webContents }
})
utils.onBeforeUnload({ preventDefault: () => {} }, proxyWindow).then(() => {
closeWebTabInWindow(windowId, tabId)
})
event.returnValue = "ok"
return
}
}
closeWebTabInWindow(windowId, tabId)
}
event.returnValue = "ok"
@ -1815,6 +1864,20 @@ function registerIPC() {
const tabId = event.sender.id
const windowId = findWindowIdByTabId(tabId)
if (windowId !== null) {
const windowData = webTabWindows.get(windowId)
if (windowData) {
const tab = windowData.views.find(v => v.id === tabId)
if (tab) {
const proxyWindow = Object.create(windowData.window, {
webContents: { get: () => tab.view.webContents }
})
utils.onBeforeUnload({ preventDefault: () => {} }, proxyWindow).then(() => {
closeWebTabInWindow(windowId, tabId)
})
event.returnValue = "ok"
return
}
}
closeWebTabInWindow(windowId, tabId)
} else {
const win = BrowserWindow.fromWebContents(event.sender)