跳转到主内容

自定义窗口

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

创建无边框窗口

无边框窗口是没有 chrome 的窗口。 不要与 Google Chrome 浏览器混淆,窗口的 chrome 是指窗口的某些部分(例如工具栏、控件等),它们不是网页的一部分。

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

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

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

标题栏样式允许隐藏浏览器窗口的大部分色彩,同时保持系统原生窗口控件完整无损,并可以在 BrowserWindow 的构造器中使用 titleBarStyle 选项来配置。

应用 hidden 标题栏样式的结果是隐藏标题栏和全尺寸内容窗口。

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

控制macOS上的红绿灯

在 macOS上,应用 hidden 标题栏样式仍然会暴露标准窗口左上方 的控制按钮(“红绿灯”)。

自定义 macOS 上红绿灯的外观

customButtonsOnHover 标题栏样式将隐藏红绿灯,直到你鼠标悬浮在上面 如果您想要在您的 HTML 中创建自定义红绿灯,但仍然 使用原生界面来控制窗口,这是有用的。

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

自定义macOS上的红绿灯位置

要修改红绿灯控件的位置,有两个配置 选项。

Applying hiddenInset title bar style will shift the vertical inset of the traffic lights by a fixed amount.

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

If you need more granular control over the positioning of the traffic lights, you can pass a set of coordinates to the trafficLightPosition option in the BrowserWindow constructor.

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

macOS上程序化显示和隐藏红绿灯

You can also show and hide the traffic lights programmatically from the main process. The win.setWindowButtonVisibility forces traffic lights to be show or hidden depending on the value of its boolean parameter.

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

Note: Given the number of APIs available, there are many ways of achieving this. For instance, combining frame: false with win.setWindowButtonVisibility(true) will yield the same layout outcome as setting titleBarStyle: 'hidden'.

Window Controls Overlay macOS Windows

The Window Controls Overlay API is a web standard that gives web apps the ability to customize their title bar region when installed on desktop. Electron exposes this API through the BrowserWindow constructor option titleBarOverlay.

This option only works whenever a custom titlebarStyle is applied on macOS or Windows. When titleBarOverlay is enabled, the window controls become exposed in their default position, and DOM elements cannot use the area underneath this region.

The titleBarOverlay option accepts two different value formats.

Specifying true on either platform will result in an overlay region with default system colors:

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

On either platform titleBarOverlay can also be an object. On both macOS and Windows, the height of the overlay can be specified with the height property. On Windows, the color of the overlay and its symbols can be specified using the color and symbolColor properties respectively. rgba(), hsla(), and #RRGGBBAA color formats are supported to apply transparency.

If a color option is not specified, the color will default to its system color for the window control buttons. Similarly, if the height option is not specified it will default to the default height:

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

Note: Once your title bar overlay is enabled from the main process, you can access the overlay's color and dimension values from a renderer using a set of readonly JavaScript APIs and CSS Environment Variables.

创建透明窗口

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

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

局限性

  • 你不能点击穿透透明区域。 详情可见: #1335
  • 透明窗口不可调整大小。 在某些平台上,将 resizable 设置为 true 可能会使透明窗口停止工作。
  • CSS blur 滤镜仅适用于网页, 因此无法对位于透明窗口下方的内容应用模糊效果 (例如在用户系统上打开的其他应用程序) 。
  • 当打开开发者工具时,窗口将不透明。
  • Windows 上:
    • 当DWM禁用时,透明窗口将失效。
    • 透明窗口不能通过Windows系统菜单或双击标题栏实现最大化。 其背后的原因可以在 #28207 这里看到
  • macOS 上:
    • 在 Mac 上, 原生窗口阴影不会显示在透明窗口中。

创建点击穿透窗口

要创建一个点击穿透窗口,也就是使窗口忽略所有鼠标事件,可以调用 win.setIgnoreMouseEvents(ignore) API:

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

macOS Windows 平台上转发鼠标事件

忽略鼠标消息会使网页内容无视鼠标移动,这意味着鼠标移动事件不会被发出。 在 Windows 操作系统上,可以使用可选参数将鼠标移动消息转发到网页,从而允许发出诸如 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;
}

提示:禁用上下文菜单

在某些平台上, 可拖拽区域将被视为non-client frame, 因此当您右键单击它时, 系统菜单将弹出。 要使上下文菜单在所有平台上都正确运行, 您永远也不要在可拖拽区域上使用自定义上下文菜单。