feat: 优化窗口管理、 IPC 处理逻辑和在 macOS 下的窗口关闭、隐藏与退出逻辑#161
feat: 优化窗口管理、 IPC 处理逻辑和在 macOS 下的窗口关闭、隐藏与退出逻辑#161LarryZhu-dev merged 2 commits intoAuto-Plugin:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
该 PR 旨在优化 Electron 主进程的窗口引用与 IPC 路由方式,避免因捕获/使用已销毁的 BrowserWindow 导致 "Object has been destroyed" 报错,并在多窗口场景下更安全地广播状态。
Changes:
- 更新模块改为向所有存活的编辑器窗口广播更新状态(不再依赖单一窗口引用)。
- 菜单点击处理改为动态获取当前可用窗口,避免闭包捕获已销毁窗口。
- IPC handlers 改为基于
event.sender/编辑器窗口集合路由,减少对“主窗口引用”的依赖。
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/main/update.ts |
新增对所有编辑器窗口的安全广播,移除对单窗口参数依赖 |
src/main/menu.ts |
菜单处理器改为运行时获取聚焦/可用窗口,避免已销毁窗口引用 |
src/main/ipcBridge.ts |
IPC 注册函数去除 win 参数,更多使用 event.sender 路由/多窗口广播 |
src/main/index.ts |
引入“安全获取可用窗口”逻辑,并调整 IPC/menu/update 注册调用方式 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /** 安全获取一个可用的编辑器窗口(优先主窗口,回退到任意存活窗口) */ | ||
| function getAvailableWindow(): BrowserWindow | null { | ||
| if (win && !win.isDestroyed()) return win; | ||
| const allWindows = BrowserWindow.getAllWindows().filter((w) => !w.isDestroyed()); |
There was a problem hiding this comment.
getAvailableWindow() 会回退到 BrowserWindow.getAllWindows() 的第一个窗口,这可能把主题编辑器窗口等非“编辑器窗口”选中,导致诸如 open-file-at-launch / DevTools / second-instance focus 等操作发到错误窗口。建议改为基于 windowManager 的 getMainWindow()/getEditorWindows() 选择目标(或至少排除 themeEditorWindow),以保证语义与注释一致且行为稳定。
| const allWindows = BrowserWindow.getAllWindows().filter((w) => !w.isDestroyed()); | |
| const allWindows = BrowserWindow.getAllWindows().filter( | |
| (w) => !w.isDestroyed() && w !== themeEditorWindow, | |
| ); |
src/main/index.ts
Outdated
| // 注册 IPC 处理程序 (在加载页面前注册,防止竞态条件) | ||
| registerIpcOnHandlers(win); | ||
| registerIpcHandleHandlers(win); | ||
| setupUpdateHandlers(win); | ||
| registerIpcOnHandlers(); | ||
| registerIpcHandleHandlers(); | ||
| setupUpdateHandlers(); | ||
|
|
||
| createMenu(win); | ||
| createMenu(); |
There was a problem hiding this comment.
registerIpcOnHandlers() 现在不再依赖窗口实例,但仍在 createWindow() 内调用;如果 createWindow() 在生命周期内被再次触发(例如 macOS activate 且窗口都被销毁后),会重复注册多个 ipcMain.on 监听,造成事件被处理多次。建议把这些全局 IPC 注册移到 app.whenReady() 只执行一次,或在注册函数内部加一次性 guard / 先 removeListener 再注册。
| const win = BrowserWindow.getFocusedWindow(); | ||
| if (win && !win.isDestroyed()) return win; | ||
| // 如果没有聚焦窗口(例如 macOS 上窗口全部隐藏),回退到第一个可见窗口 | ||
| const allWindows = BrowserWindow.getAllWindows(); |
There was a problem hiding this comment.
这里的注释写的是“回退到第一个可见窗口”,但实现只检查了 !w.isDestroyed(),没有过滤 w.isVisible()(或最小化/隐藏状态),可能把菜单事件发送到不可见窗口。建议让实现与注释对齐(优先可见窗口,若没有再回退到任意存活窗口),或者调整注释表述。
| const allWindows = BrowserWindow.getAllWindows(); | |
| const allWindows = BrowserWindow.getAllWindows(); | |
| const visibleWin = allWindows.find((w) => !w.isDestroyed() && w.isVisible()); | |
| if (visibleWin) return visibleWin; | |
| // 如果没有可见窗口,则回退到任意存活窗口 |
No description provided.