* rebase "feat: enable windows control overlay on Windows" * correct compilation error * fix linting errors * modify includes and build file * change `hidden` option to `overlay` * add patch to fix visual layout * add button background color parameter * add button text color parameter * modify `overlay` in docs and modify button hover/press transition color * change `text` to `symbol` * remove todo and fix `text` replacement * add new titleBarOverlay property and remove titleBarStyle `overlay` * update browser and frameless window docs * remove chromium patches * chore: update patches * change button hover color, update trailing `_`, update test file * add dchecks, update title bar drawing checks, update test file * modify for mac and linux builds * update docs with overlayColor and overlaySymbolColor * add corner and side hit test info * modify docs and copyright info * modify `titlebar_overlay_` as boolean or object * move `title_bar_style_ to `NativeWindow` * update docs with boolean and object titlebar_overlay_ * add `IsEmpty` checks * move get options for boolean and object checks * fix linting error * disable `use_lld` for macos * Update docs/api/frameless-window.md Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org> * Update docs/api/frameless-window.md Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org> * Update docs/api/frameless-window.md Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org> * Apply docs suggestions from code review Co-authored-by: Jeremy Rose <jeremya@chromium.org> * modify `true` option description `titleBarOverlay` * ci: cleanup keychain after tests on arm64 mac (#30472) Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org> Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com> Co-authored-by: Jeremy Rose <jeremya@chromium.org>
8.1 KiB
Frameless Window
Open a window without toolbars, borders, or other graphical "chrome".
A frameless window is a window that has no
chrome, the parts of
the window, like toolbars, that are not a part of the web page. These are
options on the BrowserWindow
class.
Create a frameless window
To create a frameless window, you need to set frame
to false
in
BrowserWindow's options
:
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ width: 800, height: 600, frame: false })
win.show()
Alternatives
There's an alternative way to specify a chromeless window on macOS and Windows.
Instead of setting frame
to false
which disables both the titlebar and window controls,
you may want to have the title bar hidden and your content extend to the full window size,
yet still preserve the window controls ("traffic lights" on macOS) for standard window actions.
You can do so by specifying the titleBarStyle
option:
hidden
Results in a hidden title bar and a full size content window. On macOS, the title bar still has the standard window controls (“traffic lights”) in the top left.
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hidden' })
win.show()
Alternatives on macOS
hiddenInset
Results in a hidden title bar with an alternative look where the traffic light buttons are slightly more inset from the window edge.
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
win.show()
customButtonsOnHover
Uses custom drawn close, and miniaturize buttons that display when hovering in the top left of the window. The fullscreen button is not available due to restrictions of frameless windows as they interface with Apple's macOS window masks. These custom buttons prevent issues with mouse events that occur with the standard window toolbar buttons. This option is only applicable for frameless windows.
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover', frame: false })
win.show()
Windows Control Overlay
When using a frameless window in conjuction with win.setWindowButtonVisibility(true)
on macOS, using one of the titleBarStyle
s as described above so
that the traffic lights are visible, or using titleBarStyle: hidden
on Windows, you can access the Window Controls Overlay JavaScript APIs and
CSS Environment Variables by setting the titleBarOverlay
option to true. Specifying true
will result in an overlay with default system colors.
On Windows, you can also specify the color of the overlay and its symbols by setting titleBarOverlay
to an object with the options color
and symbolColor
. If an option is not specified, the color will default to its system color for the window control buttons:
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: true
})
win.show()
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#2f3241',
symbolColor: '#74b1be'
}
})
win.show()
Transparent window
By setting the transparent
option to true
, you can also make the frameless
window transparent:
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ transparent: true, frame: false })
win.show()
Limitations
- You can not click through the transparent area. We are going to introduce an API to set window shape to solve this, see our issue for details.
- Transparent windows are not resizable. Setting
resizable
totrue
may make a transparent window stop working on some platforms. - The
blur
filter only applies to the web page, so there is no way to apply blur effect to the content below the window (i.e. other applications open on the user's system). - The window will not be transparent when DevTools is opened.
- On Windows operating systems,
- transparent windows will not work when DWM is disabled.
- transparent windows can not be maximized using the Windows system menu or by double clicking the title bar. The reasoning behind this can be seen on this pull request.
- On Linux, users have to put
--enable-transparent-visuals --disable-gpu
in the command line to disable GPU and allow ARGB to make transparent window, this is caused by an upstream bug that alpha channel doesn't work on some NVidia drivers on Linux. - On Mac, the native window shadow will not be shown on a transparent window.
Click-through window
To create a click-through window, i.e. making the window ignore all mouse events, you can call the win.setIgnoreMouseEvents(ignore) API:
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setIgnoreMouseEvents(true)
Forwarding
Ignoring mouse messages makes the web page oblivious to mouse movement, meaning
that mouse movement events will not be emitted. On Windows operating systems an
optional parameter can be used to forward mouse move messages to the web page,
allowing events such as mouseleave
to be emitted:
const { ipcRenderer } = require('electron')
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)
})
// Main process
const { ipcMain } = require('electron')
ipcMain.on('set-ignore-mouse-events', (event, ...args) => {
BrowserWindow.fromWebContents(event.sender).setIgnoreMouseEvents(...args)
})
This makes the web page click-through when over el
, and returns to normal
outside it.
Draggable region
By default, the frameless window is non-draggable. Apps need to specify
-webkit-app-region: drag
in CSS to tell Electron which regions are draggable
(like the OS's standard titlebar), and apps can also use
-webkit-app-region: no-drag
to exclude the non-draggable area from the
draggable region. Note that only rectangular shapes are currently supported.
Note: -webkit-app-region: drag
is known to have problems while the developer tools are open. See this GitHub issue for more information including a workaround.
To make the whole window draggable, you can add -webkit-app-region: drag
as
body
's style:
<body style="-webkit-app-region: drag">
</body>
And note that if you have made the whole window draggable, you must also mark buttons as non-draggable, otherwise it would be impossible for users to click on them:
button {
-webkit-app-region: no-drag;
}
If you're only setting a custom titlebar as draggable, you also need to make all buttons in titlebar non-draggable.
Text selection
In a frameless window the dragging behavior may conflict with selecting text. For example, when you drag the titlebar you may accidentally select the text on the titlebar. To prevent this, you need to disable text selection within a draggable area like this:
.titlebar {
-webkit-user-select: none;
-webkit-app-region: drag;
}
Context menu
On some platforms, the draggable area will be treated as a non-client frame, so when you right click on it a system menu will pop up. To make the context menu behave correctly on all platforms you should never use a custom context menu on draggable areas.