跳至主要内容

窗口自定义

BrowserWindow 模块是 Electron 应用程序的基础,它提供了许多 API,可以更改浏览器窗口的外观和行为。在本教程中,我们将介绍 macOS、Windows 和 Linux 上窗口自定义的各种用例。

创建无边框窗口

无边框窗口是没有边框的窗口。不要与 Google Chrome 浏览器混淆,窗口边框是指窗口中不属于网页的部分(例如工具栏、控件)。

要创建无边框窗口,需要在 BrowserWindow 构造函数中将 frame 设置为 false

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ frame: false })

应用自定义标题栏样式 macOS Windows

标题栏样式允许你隐藏 BrowserWindow 的大部分边框,同时保持系统的原生窗口控件完好无损,并且可以使用 BrowserWindow 构造函数中的 titleBarStyle 选项进行配置。

应用 hidden 标题栏样式会导致隐藏标题栏和全尺寸内容窗口。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hidden' })

控制交通信号灯 macOS

在 macOS 上,应用 hidden 标题栏样式仍会显示左上角的标准窗口控件(“交通信号灯”)。

自定义交通信号灯的外观 macOS

customButtonsOnHover 标题栏样式会在你将鼠标悬停在上面之前隐藏交通信号灯。如果你想在 HTML 中创建自定义交通信号灯,但仍使用原生 UI 来控制窗口,这将非常有用。

const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover' })

自定义交通信号灯位置 macOS

要修改交通信号灯窗口控件的位置,有两个可用的配置选项。

应用 hiddenInset 标题栏样式会将交通信号灯的垂直内嵌偏移一个固定量。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })

如果你需要对交通信号灯的位置进行更精细的控制,可以将一组坐标传递给 BrowserWindow 构造函数中的 trafficLightPosition 选项。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
trafficLightPosition: { x: 10, y: 10 }
})

以编程方式显示和隐藏交通信号灯 macOS

您还可以从主进程以编程方式显示和隐藏交通信号灯。win.setWindowButtonVisibility 根据其布尔参数的值强制显示或隐藏交通信号灯。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
// hides the traffic lights
win.setWindowButtonVisibility(false)

注意:鉴于可用的 API 数量,实现此目的的方法有很多。例如,将 frame: falsewin.setWindowButtonVisibility(true) 相结合将产生与设置 titleBarStyle: 'hidden' 相同的布局结果。

窗口控件叠加 macOS Windows

窗口控件叠加 API 是一项 Web 标准,当在桌面上安装时,它使 Web 应用程序能够自定义其标题栏区域。Electron 通过 BrowserWindow 构造函数选项 titleBarOverlay 公开了此 API。

此选项仅在 macOS 或 Windows 上应用自定义 titlebarStyle 时才起作用。启用 titleBarOverlay 时,窗口控件将显示在其默认位置,并且 DOM 元素无法使用此区域下方的区域。

titleBarOverlay 选项接受两种不同的值格式。

在任一平台上指定 true 将生成具有默认系统颜色的叠加区域

main.js
// on macOS or Windows
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: true
})

在任一平台上,titleBarOverlay 也可以是一个对象。在 macOS 和 Windows 上,可以使用 height 属性指定叠加的高度。在 Windows 上,可以使用 colorsymbolColor 属性分别指定叠加及其符号的颜色。支持 rgba()hsla()#RRGGBBAA 颜色格式以应用透明度。

如果未指定颜色选项,则颜色将默认为窗口控制按钮的系统颜色。同样,如果未指定高度选项,则它将默认为默认高度

main.js
// on Windows
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#2f3241',
symbolColor: '#74b1be',
height: 60
}
})

注意:一旦从主进程启用了标题栏覆盖,即可使用一组只读 JavaScript APICSS 环境变量 从渲染器访问覆盖的颜色和维度值。

创建透明窗口

通过将 transparent 选项设置为 true,可以创建一个完全透明的窗口。

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ transparent: true })

限制

  • 无法点击透明区域。有关详细信息,请参阅 #1335
  • 透明窗口不可调整大小。在某些平台上,将 resizable 设置为 true 可能会导致透明窗口停止工作。
  • CSS blur() 滤镜仅适用于窗口的网络内容,因此无法对窗口下方的内容(即用户系统上打开的其他应用程序)应用模糊效果。
  • 打开 DevTools 时,窗口将不会透明。
  • Windows
    • 禁用 DWM 时,透明窗口将不起作用。
    • 无法使用 Windows 系统菜单或双击标题栏最大化透明窗口。其背后的原因可以在 PR #28207 中看到。
  • macOS
    • 透明窗口上不会显示本机窗口阴影。

创建可点击窗口

要创建可点击窗口(即让窗口忽略所有鼠标事件),可以调用 win.setIgnoreMouseEvents(ignore) API

main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setIgnoreMouseEvents(true)

转发鼠标事件 macOS Windows

忽略鼠标消息会使网页内容对鼠标移动无感,这意味着不会发出鼠标移动事件。在 Windows 和 macOS 上,可以使用可选参数将鼠标移动消息转发到网页,从而允许发出诸如 mouseleave 之类的事件

main.js
const { BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')

const win = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})

ipcMain.on('set-ignore-mouse-events', (event, ignore, options) => {
const win = BrowserWindow.fromWebContents(event.sender)
win.setIgnoreMouseEvents(ignore, options)
})
preload.js
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 的样式

styles.css
body {
-webkit-app-region: drag;
}

请注意,如果你已将整个窗口设为可拖动,则还必须将按钮标记为不可拖动,否则用户将无法单击它们

styles.css
button {
-webkit-app-region: no-drag;
}

如果你仅将自定义标题栏设置为可拖动,则还需要使标题栏中的所有按钮不可拖动。

提示:禁用文本选择

创建可拖动区域时,拖动行为可能会与文本选择冲突。例如,当你拖动标题栏时,你可能会意外选择其文本内容。为了防止这种情况,你需要在可拖动区域内禁用文本选择,如下所示

.titlebar {
-webkit-user-select: none;
-webkit-app-region: drag;
}

提示:禁用上下文菜单

在某些平台上,可拖动区域将被视为非客户端框架,因此当你右键单击它时,将弹出系统菜单。为了使上下文菜单在所有平台上都能正常运行,你绝不应在可拖动区域上使用自定义上下文菜单。