loading
Warning:
Installed desktop apps only The overlay exists for an installed desktop app whose manifest sets "display_override": ["window-controls-overlay"], and the user can switch it off from the app's own menu. In a browser tab IsVisible is false and the geometry is all zeros - which is exactly what you should design for.
Note:
The CSS half The same rectangle is available to CSS as the titlebar-area-x, titlebar-area-y, titlebar-area-width and titlebar-area-height environment variables, and app-region: drag marks the part of your header that moves the window. Use CSS for the layout and this service for the logic that CSS cannot express.

Support and visibility

IsSupported / IsVisible

Supported is not the same as visible: a supporting browser still reports an invisible overlay for a page running in a tab. During prerender/SSR both return false rather than throwing.

C#
@inject Bit.Butil.WindowControlsOverlay overlay

if (await overlay.IsVisible())
{
    // we are drawing our own title bar
}
Live sample
support check output
Results will appear here when you interact with the samples.

Where your content may go

GetTitlebarAreaRect

The rectangle your own content may use. It starts after the window controls on the leading side and stops before them on the trailing side, which is why X is not always zero - a toolbar that ignores it ends up underneath the close button.

C#
var rect = await overlay.GetTitlebarAreaRect();

// rect.X is the left edge you may draw from,
// rect.Width how much room you have, rect.Height how tall the bar is.
Live sample
geometry output
Results will appear here when you interact with the samples.

Follow the geometry

OnGeometryChange

Fires when the window is resized and when the user toggles the overlay, and once immediately with the current geometry so a subscriber can lay out before anything changes. Dispose the returned subscription.

C#
_sub = await overlay.OnGeometryChange(geometry =>
{
    _titlebarPadding = geometry.X;
    InvokeAsync(StateHasChanged);
});
Live sample
geometrychange output
Results will appear here when you interact with the samples.

API reference

Member
Signature
Description
IsSupported
ValueTask<bool> IsSupported()
True when the runtime exposes navigator.windowControlsOverlay (Chromium desktop).
IsVisible
ValueTask<bool> IsVisible()
True while the app is actually drawing its own title bar.
GetTitlebarAreaRect
ValueTask<WindowControlsOverlayGeometry> GetTitlebarAreaRect()
The rectangle your content may draw in, in CSS pixels relative to the viewport.
OnGeometryChange
Task<ButilSubscription> OnGeometryChange(Action<WindowControlsOverlayGeometry> handler)
Watches the overlay. Fires on resize and on toggle, plus once immediately with the current geometry.
DisposeAsync
ValueTask DisposeAsync()
Detaches every listener registered through this instance and releases its interop reference.
An unhandled error has occurred. Reload 🗙