Electron 自定义窗口
BrowserWindow
模块是您的 Electron 应用程序的基础。 并且它暴露了许多可以改变您浏览器窗口的外观和行为的API。 在本教程中,我们将介绍在macOS,Windows和Linux上自定义窗口的各种用例。
创建无边框窗口
无边框窗口是没有 chrome 的窗口。 不要与 Google Chrome 浏览器混淆,窗口的 chrome 是指窗口的某些部分(例如工具栏、控件等),它们不是网页的一部分。
要创建无边框窗口,需在 BrowserWindow
的构造中将 frame
参数设置为 false
:
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ frame: false })
应用自定义标题栏样式
标题栏样式允许隐藏浏览器窗口的大部分色彩,同时保持系统原生窗口控件完整无损,并可以在 BrowserWindow
的构造器中使用 titleBarStyle
选项来配置。
应用 hidden
标题栏样式的结果是隐藏标题栏和全尺寸内容窗口。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hidden' })
控制红绿灯
在 macOS 上,应用隐藏标题栏样式仍会在左上角显示标准窗口控件(“红绿灯”)。
自定义交通灯的外观
customButtonsOnHover
标题栏样式将隐藏交通灯,直到您将鼠标悬停在它们上方。如果您想在 HTML 中创建自定义交通灯但仍使用本机 UI 来控制窗口,这将很有用。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover' })
自定义红绿灯位置
要修改红绿灯窗口控件的位置,有两个可用的配置选项。
应用 hiddenInset
标题栏样式会将交通灯的垂直插入移动固定量。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
如果您需要对交通灯的定位进行更精细的控制,您可以将一组坐标传递给 BrowserWindow
构造函数中的 trafficLightPosition
选项。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
trafficLightPosition: { x: 10, y: 10 }
})
以编程方式显示和隐藏交通灯
您还可以在主进程中以编程方式显示和隐藏红绿灯。 win.setWindowButtonVisibility
根据其布尔参数的值强制显示或隐藏交通灯。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
// hides the traffic lights
win.setWindowButtonVisibility(false)
注意:考虑到可用 API 的数量,有很多方法可以实现这一点。例如,将
frame: false
与 win.setWindowButtonVisibility(true)
组合将产生与设置 titleBarStyle: 'hidden'
相同的布局结果。
窗口控件覆盖
Window Controls Overlay API 是一种网络标准,它使网络应用程序能够在安装到桌面时自定义其标题栏区域。 Electron 通过 BrowserWindow
构造函数选项 titleBarOverlay
公开此 API。
只有在 macOS 或 Windows 上应用自定义 titlebarStyle
时,此选项才有效。启用 titleBarOverlay
后,窗口控件会在其默认位置公开,并且 DOM 元素无法使用该区域下方的区域。
titleBarOverlay
选项接受两种不同的值格式。
在任一平台上指定 true
将导致覆盖区域具有默认系统颜色:
// on macOS or Windows
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: true
})
在任一平台上,titleBarOverlay
也可以是一个对象。在 macOS 和 Windows 上,可以使用 height
属性指定叠加层的高度。在 Windows 上,可以分别使用 color
和 symbolColor
属性指定叠加层及其符号的颜色。
如果未指定颜色选项,则颜色将默认为窗口控制按钮的系统颜色。同样,如果未指定高度选项,它将默认为默认高度:
// on Windows
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#2f3241',
symbolColor: '#74b1be',
height: 60
}
})
注意:从主进程启用标题栏覆盖后,您可以使用一组只读 JavaScript API 和 CSS 环境变量从渲染器访问覆盖的颜色和尺寸值。
局限性
- 目前不支持透明颜色。可以在 PR #33567 中找到此功能的进度更新。
创建透明窗口
通过设置 transparent
选项为 true
,您可以创建一个完全透明的窗口。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ transparent: true })
局限性
- 你不能点击穿透透明区域。 详情可见: #1335。
- 透明窗口不可调整大小。 在某些平台上,将
resizable
设置为true
可能会使透明窗口停止工作。 CSS blur() 过滤器仅适用于窗口的 Web 内容,因此无法对窗口下方的内容应用模糊效果(即用户系统上打开的其他应用程序)。
- 当打开开发者工具时,窗口将不透明。
- 在 Windows 上:
- 当DWM禁用时,透明窗口将失效。
- 透明窗口不能通过Windows系统菜单或双击标题栏实现最大化。 其背后的原因可以在 #28207 这里看到
- 在 macOS 上:
- 在 Mac 上, 原生窗口阴影不会显示在透明窗口中。
创建点击穿透窗口
要创建一个点击穿透窗口,也就是使窗口忽略所有鼠标事件,可以调用 win.setIgnoreMouseEvents(ignore)
API:
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setIgnoreMouseEvents(true)
在 macOS Windows 平台上转发鼠标事件
忽略鼠标消息会使网页内容无视鼠标移动,这意味着鼠标移动事件不会被发出。 在 Windows 操作系统上,可以使用可选参数将鼠标移动消息转发到网页,从而允许发出诸如 mouseleave
之类的事件:
const { BrowserWindow, ipcMain } = require('electron')
const path = require('path')
const win = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
ipcMain.on('set-ignore-mouse-events', (event, ...args) => {
const win = BrowserWindow.fromWebContents(event.sender)
win.setIgnoreMouseEvents(...args)
})
window.addEventListener('DOMContentLoaded', () => {
const el = document.getElementById('clickThroughElement')
el.addEventListener('mouseenter', () => {
ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
})
el.addEventListener('mouseleave', () => {
ipcRenderer.send('set-ignore-mouse-events', false)
})
})
这将使网页在 #clickThroughElement
上点击时穿透,在它外面时恢复正常。
设置自定义可拖动区域
默认情况下, 无边框窗口是不可拖拽的。 应用程序需要在 CSS 中指定 -webkit-app-region: drag
来告诉 Electron 哪些区域是可拖拽的(如操作系统的标准标题栏),在可拖拽区域内部使用 -webkit-app-region: no-drag
则可以将其中部分区域排除。 请注意, 当前只支持矩形形状。
要使整个窗口可拖拽, 您可以添加 -webkit-app-region: drag
作为 body
的样式:
body {
-webkit-app-region: drag;
}
请注意,如果您使整个窗口都可拖拽,则必须将其中的按钮标记为不可拖拽,否则用户将无法点击它们:
button {
-webkit-app-region: no-drag;
}
如果只将自定义标题栏设置为可拖拽,还需要使标题栏中的所有按钮都不可拖拽。
提示:禁用文本选择
创建可拖拽区域时,拖拽行为可能与文本选择相冲突。 例如,当您拖动标题栏时,您可能不小心选中其中的文本。 为了避免这种情况,您需要在可拖拽区域中禁用文本选择,像这样:
.titlebar {
-webkit-user-select: none;
-webkit-app-region: drag;
}
提示:禁用上下文菜单
在某些平台上, 可拖拽区域将被视为non-client frame, 因此当您右键单击它时, 系统菜单将弹出。 要使上下文菜单在所有平台上都正确运行, 您永远也不要在可拖拽区域上使用自定义上下文菜单。
更多建议: