Window Controls Overlay for Frameless Desktop PWAs
The Window Controls Overlay (WCO) API enables Progressive Web Apps (PWAs) on desktop operating systems to build fully customized, frameless title bars by reclaiming the space traditionally reserved for the operating system window chrome. By default, desktop PWAs run within an OS-provided window frame containing an arbitrary title bar and native controls for minimizing, maximizing, and closing the app. The WCO API frees up this vertical space, allowing developers to extend web content across the entire window surface while keeping native control buttons functional, accessible, and correctly placed.
The Problem with Default Desktop Window Frames
Standard desktop PWAs forfeit a strip of vertical screen space to the operating system's default title bar. This bar typically displays the app's title and an arbitrary background color defined in the web app manifest, producing a visual separation that distinguishes the PWA from modern native desktop applications like Spotify, Discord, or VS Code. These native applications integrate elements like search bars, breadcrumbs, custom tabs, and account switchers directly into their top window edge. Without the WCO API, web developers cannot access this top region.
Enabling the Window Controls Overlay
Activating the overlay begins in the Web App Manifest. Developers
declare the feature using the display_override member:
{
"name": "Custom Desktop App",
"display_override": ["window-controls-overlay"]
}When this value is present, supporting desktop browsers collapse the default title bar into a floating overlay containing only the mandatory platform control buttons (minimize, maximize, close) and browser-required security indicators. The rest of the window header becomes standard HTML layout space.
Managing Layouts with CSS Environment Variables
To prevent application content from overlapping the platform window buttons, the WCO specification provides dedicated CSS environment variables. These variables expose the position and dimensions of the usable title bar area:
env(titlebar-area-x)env(titlebar-area-y)env(titlebar-area-width)env(titlebar-area-height)
Developers use these values to anchor custom headers precisely. For example, setting a custom toolbar's position and size to match these variables guarantees that controls will not render underneath the platform buttons, regardless of whether the operating system places those buttons on the left (macOS) or right (Windows and Linux).
Additionally, developers apply the CSS property
app-region: drag (or the standardized
-webkit-app-region: drag) to designate regions that allow
users to drag the entire window, and app-region: no-drag to
nested interactive elements like inputs, menus, and buttons.
Dynamic Adaptations with JavaScript
The API exposes a JavaScript interface on
navigator.windowControlsOverlay that allows apps to react
dynamically to changes in the window frame state. Through this
interface, developers can:
- Check
navigator.windowControlsOverlay.visibleto verify if the overlay is active. - Call
navigator.windowControlsOverlay.getTitlebarAreaRect()to inspect the exact bounding rectangle of the available title bar space. - Listen for the
geometrychangeevent to update layout components immediately when the user resizes the window, toggles full-screen mode, or changes OS display scaling.
Architectural and Experience Impact
The Window Controls Overlay API bridges the visual gap between desktop web applications and native software. By giving developers control over the window header while maintaining platform-native accessibility and controls, it maximizes usable screen space and delivers a seamless, frameless desktop experience.