跳到主要内容

模态窗口、父子窗口和 alwaysOnTop 的层级怎么处理?

考察点​

  • parent / modal 的平台差异
  • 置顶窗口把对话框挡在后面一类问题

参考答案​

1. 父子窗口​

const child = new BrowserWindow({
parent: mainWindow, // 子窗口跟着父窗口最小化、关闭
modal: true, // 模态:父窗口在子窗口关掉前不能操作
width: 480,
height: 320,
show: false,
});

效果:

  • 父窗口关闭,子窗口一起关
  • 父窗口最小化,子窗口跟着隐藏
  • modal: true 时,用户无法把焦点点回父窗口

macOS 上模态更接近 sheet 的交互预期;Windows 上是禁用父窗口。Linux 视桌面环境而定,模态不一定可靠,关键流程要在应用内再挡一层,不能只靠操作系统。

2. alwaysOnTop​

win.setAlwaysOnTop(true, 'floating'); // level:normal / floating / screen-saver 等

置顶级别高于普通窗口,也常常高于自己的 dialog.showMessageBox。现象是:提示框跑到置顶窗口后面,用户以为应用卡死。

处理:

  • 弹出对话框前先 setAlwaysOnTop(false),关完再恢复
  • 或者把对话框的 parent 设成这个置顶窗口
  • 录屏小窗、悬浮球才需要一直置顶,主界面不要全局置顶

3. 多个子窗口​

BrowserWindow.getFocusedWindow() 在模态打开时可能是子窗口。IPC 里不要假设“焦点窗口就是主窗口”,用 event.sender 反查。

关闭顺序:如果业务要求“设置没保存不能关主窗口”,在父窗口的 close 里检查子窗口状态,而不是只依赖 modal。

面试话术​

附属窗口用 parent,需要卡住父窗口再用 modal。alwaysOnTop 会把系统对话框压到后面,弹框前先取消置顶或把对话框挂到这个窗口上。Linux 上模态不完全可靠。IPC 用 event.sender 找窗口,不用焦点窗口猜。

常见追问​

  • 子窗口能有自己的 preload 吗? 可以,而且应该更小。设置窗口不必继承主窗口的全部 API。
  • 全屏窗口再开模态会怎样? macOS 全屏空间里子窗口可能跑到另一桌面。全屏时改用页面内对话框更稳。