app-region CSS property for draggable windows
The app-region CSS property defines areas of a window that can be dragged. Setting app-region: drag marks a rectangular area as draggable. Setting app-region: no-drag excludes a rectangular area from a draggable region, re-enabling pointer events in that area.
Draggable areas ignore pointer events
Draggable areas defined with app-region: drag ignore all pointer events. For example, a button element that overlaps a draggable region will not emit mouse clicks or mouse enter/exit events within that overlapping area.
Making entire window draggable
To make the whole window draggable, add app-region: drag as the body's style. When the entire window is draggable, you must also mark buttons as non-draggable using app-region: no-drag, otherwise users cannot click them.
Disable text selection in draggable regions
When creating a draggable region, the dragging behavior may conflict with text selection. To prevent accidentally selecting text while dragging, disable text selection within a draggable area using the CSS property user-select: none.
Avoid custom context menus on draggable areas
On some platforms, the draggable area will be treated as a non-client frame, so right-clicking on it will pop up a system menu. To make the context menu behave correctly on all platforms, never use a custom context menu on draggable areas.
Create click-through windows with setIgnoreMouseEvents
To create a click-through window that ignores all mouse events, call the win.setIgnoreMouseEvents(ignore) API with ignore set to true.
Forward mouse events in click-through windows
On Windows and macOS, win.setIgnoreMouseEvents(ignore, options) accepts an optional parameter. Passing {forward: true} forwards mouse move messages to the web page, allowing events such as mouseleave to be emitted even when the window is ignoring mouse events.
Example: draggable window with non-draggable buttons
```css
body {
app-region: drag;
}
button {
app-region: no-drag;
}
```
This makes the entire window draggable while keeping buttons clickable.
Example: disable text selection in title bar
```css
.titlebar {
user-select: none;
app-region: drag;
}
```
This prevents text selection conflicts when dragging a custom title bar.
Example: click-through window with mouse event forwarding
```js
// 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)
})
```
```js
// 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)
})
})
```
This makes the web page click-through when over a specific element, and returns to normal outside it.
Dock API access via app.dock
The Dock API is exposed via the Dock class accessible through the app.dock property. There is a single Dock instance per Electron application, and this property only exists on macOS.
Dock menu triggered by right-click or Ctrl-click
The Dock menu is triggered by right-clicking or Ctrl-clicking the app icon on macOS. By default, the app's Dock menu includes system-provided window management utilities, including the ability to show all windows, hide the app, and switch between different open windows.
dock.setMenu() must be called after ready event
The dock.setMenu() API only works after the 'ready' event is fired. To set an app-defined custom Dock menu, pass a Menu instance into the dock.setMenu API.
Dock context menus do not need menu.popup() instrumentation
Unlike with regular context menus, Dock context menus do not need to be manually instrumented using the menu.popup API. Instead, the Dock object handles click events automatically.
Example: Setting a custom Dock menu
const { app, BrowserWindow, Menu } = require('electron/main')
app.whenReady().then(() => {
const dockMenu = Menu.buildFromTemplate([
{
label: 'New Window',
click: () => { const win = new BrowserWindow() }
}
])
app.dock?.setMenu(dockMenu)
})
app.dock is undefined on non-macOS platforms
The app.dock property only exists on macOS. When accessing it, use optional chaining (app.dock?.setMenu) to avoid errors on other platforms.
webContents.startDrag() API for native file drag
To implement native file drag and drop in Electron, call the webContents.startDrag(item) API in response to the ondragstart event. This enables dragging files and content out from web content into the operating system.
Renderer process drag event handling
In the renderer process, attach an ondragstart event listener to a draggable element and call window.electron.startDrag() with the file name. The event.preventDefault() must be called to prevent default browser behavior.
Dragging files into Electron app uses standard web API
Dragging files into an Electron app uses the standard HTML Drag and Drop web API from MDN, not a special Electron API.
setProgressBar API call syntax
Call the setProgressBar() method on a BrowserWindow instance with a number between 0 and 1 to display progress. For example, setProgressBar(0.63) indicates 63% completion.
Progress bar parameter values and behavior
Values between 0 and 1 show progress percentage. Negative values (e.g. -1) remove the progress bar. Values greater than 1 show an indeterminate progress bar on Windows or clamp to 100% on other operating systems. Indeterminate progress bars remain active but do not show an actual percentage, used when operation duration is unknown.
Progress bar platform support and limitations
On Windows, each window can have its own progress bar displayed in the taskbar button. On macOS, progress bars display as part of the dock icon and only one progress bar is shown per application. Linux does not support progress bars.
Progress bar example code
const { app, BrowserWindow } = require('electron/main')
let progressInterval
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
const INCREMENT = 0.03
const INTERVAL_DELAY = 100 // ms
let c = 0
progressInterval = setInterval(() => {
// update progress bar to next value
// values between 0 and 1 will show progress, >1 will show indeterminate or stick at 100%
win.setProgressBar(c)
// increment or reset progress bar
if (c < 2) {
c += INCREMENT
} else {
c = (-INCREMENT * 5) // reset to a bit less than 0 to show reset state
}
}, INTERVAL_DELAY)
}
app.whenReady().then(createWindow)
// before the app is terminated, clear both timers
app.on('before-quit', () => {
clearInterval(progressInterval)
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
Progress bar visibility in macOS Mission Control
On macOS, the progress bar is also visible in Mission Control, providing progress information in the application switcher view.
Minimize to tray with window-all-closed event
To keep an app and its system tray icon alive when all windows are closed, listen to the 'window-all-closed' event on the app module. Having this listener active prevents the app from quitting. By default, base Electron templates quit the app on Windows and Linux to emulate standard OS behavior.
BrowserWindow can only be created after app ready event
BrowserWindows can only be created after the app module's 'ready' event is fired. Use app.whenReady() to wait for this event before calling createWindow().
Quit app when all windows closed on Windows and Linux
On Windows and Linux, listen for the app module's 'window-all-closed' event and call app.quit() to exit the app if the user is not on macOS. This implements the pattern where closing all windows quits the application entirely.
macOS apps should reopen window when activated with no windows
On macOS, apps typically continue running without any windows open. Listen for the app module's 'activate' event inside the whenReady() callback and call createWindow() if BrowserWindow.getAllWindows().length === 0 to open a new window when the app is activated.
BrowserWindow basic example with 800x600 dimensions
Example of creating a BrowserWindow and loading an HTML file:
const { app, BrowserWindow } = require('electron')
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
})
Window State Persistence overview
Window State Persistence allows an Electron application to automatically save and restore a window's position, size, and display modes (such as maximized or fullscreen states) across application restarts. This is useful for applications where users frequently resize, move, or maximize windows and expect them to remain in the same state when reopening the app.
Enable Window State Persistence with windowStatePersistence option
To enable Window State Persistence, set windowStatePersistence: true in the BrowserWindow or BaseWindow constructor options and provide a unique name property for the window. The name serves as the identifier for storing and retrieving the window's saved state.
Window State Persistence automatic behaviors
When windowStatePersistence is enabled, Electron automatically: (1) restores the window's position, size, and display mode when created if a previous state exists; (2) saves the window state whenever it changes; (3) emits a 'persisted-state-restored' event after successfully restoring state; (4) adapts restored window state to multi-monitor setups and display changes automatically.
Selective Window State Persistence with bounds and displayMode options
Window State Persistence can be configured selectively by passing an object to windowStatePersistence with options: bounds (boolean, default: true) to save position and size, and displayMode (boolean, default: true) to save maximized/fullscreen/kiosk state. For example, setting displayMode to false means the window will always start in normal mode even if it was maximized when last closed.
Clear persisted window state programmatically
Use the static method BrowserWindow.clearPersistedState(windowName) to programmatically clear the saved state for a specific window. After clearing, when you create a window with that name, it will use the default constructor options instead of restored state.
Window State Persistence selective persistence example
const { app, BrowserWindow } = require('electron')
function createWindow () {
const win = new BrowserWindow({
name: 'main-window',
width: 800,
height: 600,
windowStatePersistence: {
bounds: true, // Save position and size (default: true)
displayMode: false // Don't save maximized/fullscreen/kiosk state (default: true)
}
})
win.loadFile('index.html')
}
app.whenReady().then(createWindow)
Clear persisted window state example
const { BrowserWindow } = require('electron')
// Clear saved state for a specific window
BrowserWindow.clearPersistedState('main-window')
// Now when you create a window with this name,
// it will use the default constructor options
const win = new BrowserWindow({
name: 'main-window',
width: 800,
height: 600,
windowStatePersistence: true
})
Window State Persistence available on BaseWindow and BrowserWindow
The Window State Persistence APIs are available on both BaseWindow and BrowserWindow (since BrowserWindow extends BaseWindow) and work identically.
JumpList custom context menu for taskbar
Windows allows apps to define a custom context menu called a JumpList that shows when users right-click the app's icon in the taskbar. Custom actions are specified in the Tasks category of the JumpList.
JumpList tasks should be context-free and common
JumpList tasks should be context-free, meaning the application does not need to be running for them to work. Tasks should be the statistically most common actions that a normal user would perform, such as composing an email or opening a calendar. Tasks should not include advanced features or one-time actions like registration, and should not be used for promotional items like upgrades or special offers.
JumpList task list should remain static
The task list in a JumpList should be static and remain the same regardless of the application's state or status. While it is technically possible to vary the list dynamically, this should be avoided because it could confuse users who do not expect that portion of the destination list to change.
app.setUserTasks API for setting JumpList tasks
Use the app.setUserTasks API to set user tasks for your application. Pass an array of task objects, each with program, arguments, iconPath, iconIndex, title, and description properties. To clear tasks, call app.setUserTasks with an empty array.
JumpList task example with app.setUserTasks
Example of setting user tasks with app.setUserTasks:
const { app } = require('electron')
app.setUserTasks([
{
program: process.execPath,
arguments: '--new-window',
iconPath: process.execPath,
iconIndex: 0,
title: 'New Window',
description: 'Create a new window'
}
])
JumpList tasks persist after application closes
User tasks will still be displayed even after closing the application, so the icon and program path specified for a task should exist until the application is uninstalled.
Thumbnail toolbar on Windows taskbar
On Windows, a thumbnail toolbar can be added to a taskbar layout with specified buttons, providing users a way to access a particular window's commands without restoring or activating the window. The toolbar can have a maximum of seven buttons, and each button has an ID, image, tooltip, and state.
BrowserWindow.setThumbarButtons API
Use BrowserWindow.setThumbarButtons to set thumbnail toolbar buttons in your application. Pass an array of button objects, each with tooltip, icon, optional flags, and click handler properties. To clear buttons, call with an empty array.
Thumbnail toolbar button example
Example of setting thumbnail toolbar buttons:
const { BrowserWindow, nativeImage } = require('electron')
const path = require('node:path')
const win = new BrowserWindow()
win.setThumbarButtons([
{
tooltip: 'button1',
icon: nativeImage.createFromPath(path.join(__dirname, 'button1.png')),
click () { console.log('button1 clicked') }
}, {
tooltip: 'button2',
icon: nativeImage.createFromPath(path.join(__dirname, 'button2.png')),
flags: ['enabled', 'dismissonclick'],
click () { console.log('button2 clicked.') }
}
])
Icon overlay for taskbar button status
On Windows, a taskbar button can display a small icon overlay to show application status. Icon overlays are intended to supply important, long-standing status or notifications such as network status, messenger status, or new mail. Users should not be presented with constantly changing overlays or animations.
BrowserWindow.setOverlayIcon API
Use BrowserWindow.setOverlayIcon to set the overlay icon for a window. The API takes a nativeImage and a description string as parameters.
Overlay icon example
Example of setting an overlay icon:
const { BrowserWindow, nativeImage } = require('electron')
const win = new BrowserWindow()
win.setOverlayIcon(nativeImage.createFromPath('path/to/overlay.png'), 'Description for overlay')
Flash frame to highlight taskbar button
On Windows, you can highlight the taskbar button by flashing it to get the user's attention. This is similar to bouncing the dock icon in macOS. Flashing is typically used to inform the user that the window requires attention but does not currently have keyboard focus.
BrowserWindow.flashFrame API
Use BrowserWindow.flashFrame to flash the taskbar button. Pass true to start flashing and false to stop. Remember to call with false to turn off the flash, typically when the window receives focus or after a timeout.
Flash frame example
Example of flashing the taskbar button:
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.once('focus', () => win.flashFrame(false))
win.flashFrame(true)
TouchBarOtherItemsProxy nests Chromium-inherited TouchBar elements
TouchBarOtherItemsProxy instantiates a special proxy that nests TouchBar elements inherited from Chromium at the space indicated by the proxy. By default, this proxy is added to each TouchBar at the end of the input.
Only one TouchBarOtherItemsProxy instance per TouchBar
Only one instance of the TouchBarOtherItemsProxy class can be added per TouchBar.
TouchBarOtherItemsProxy not exported from electron module
TouchBarOtherItemsProxy is not exported from the 'electron' module. It is only available as a return value of other methods in the Electron API.