背景
使用Electron 创建一个无边框切透明的窗口,实现UI定制,窗体隐藏后会出现任务栏托盘中,然后点击任务栏托盘中的应用程序图标将其展示出来。
环境
windows 7+ 操作系统
闪烁描述
调用hide()方法隐藏窗体,在调用show()方法是出现了窗口闪屏
配置代码
const defaultConfig: BrowserWindowConstructorOptions = {
frame: false, // 关闭窗口边框
transparent: true, // 透明 ( 如果这里为true,会导致窗口隐藏后再显示是会出现闪烁的问题 )
backgroundColor: '#ffffffff', // 窗口背景色
fullscreenable: false, // 止全屏模式
resizable: false, // 可缩放
maximizable: true, // 最大化按钮
minimizable: true, // 最小化按钮
show: false, // 初始时不显示窗口
titleBarStyle: 'hidden', // 隐藏标题栏
skipTaskbar: false, // 在任务栏中显示窗口
alwaysOnTop: false, // 不总是置顶
autoHideMenuBar: true, // 自动隐藏菜单栏
};
三、原因分析
透明窗口依赖 GPU 渲染
当设置 transparent: true 时,Electron 使用的是 Chromium 的透明渲染通道,依赖 GPU 加速。
在窗口隐藏 (hide()) 和显示 (show()) 切换时,GPU 上下文可能被释放或重置,导致重新绘制时出现闪烁。窗口内容未准备好即展示
调用 show() 时如果页面尚未完成加载或渲染,会导致视觉上的“空白帧”,从而产生闪烁感。窗口动画与合成器行为影响
某些操作系统(特别是 Windows)在处理透明窗口动画和合成器层时,可能会因为切换状态造成画面短暂不一致
四、解决方案
方案一:
将窗口配置中的 transparent 设置为 false;
const defaultConfig: BrowserWindowConstructorOptions = {
frame: false, // 关闭窗口边框
transparent: false, // 透明 ( 如果这里为true,会导致窗口隐藏后再显示是会出现闪烁的问题 )
backgroundColor: '#ffffffff', // 窗口背景色
fullscreenable: false, // 止全屏模式
resizable: false, // 可缩放
maximizable: true, // 最大化按钮
minimizable: true, // 最小化按钮
show: false, // 初始时不显示窗口
titleBarStyle: 'hidden', // 隐藏标题栏
skipTaskbar: false, // 在任务栏中显示窗口
alwaysOnTop: false, // 不总是置顶
autoHideMenuBar: true, // 自动隐藏菜单栏
};
方案二:
窗口配置中的transparent 如果非要设置为true,那么请增加如下配置
/*
* 禁用窗口管理器的动画效果
*/
app.commandLine.appendSwitch('wm-window-animations-disabled');
// 配置解答:
1. app.commandLine:这是 Electron 的 app 模块提供的一个对象,用于操作 Chromium 的命令行参数
2. appendSwitch:该方法用于添加一个命令行开关。它接受两个参数,第一个是开关名称,第二个是可选值(如果不需要值,则只传入开关名即可)。
3. 'wm-window-animations-disabled':这是一个 Chromium 支持的命令行开关,表示禁用窗口动画(如打开、关闭、最小化等过渡动画)。
// 使用场景
1. 在某些性能敏感的应用中,禁用窗口动画可以减少 GPU 和 CPU 的负载。
2. 对于自动化测试或嵌入式界面,窗口动画可能没有意义甚至造成干扰。
示例代码
const { app } = require('electron');
app.commandLine.appendSwitch('wm-window-animations-disabled');
app.whenReady().then(() => {
// 创建窗口等操作
});