Signatur
Beschreibung
Die Schnittstelle WindowControlsOverlay gehört zur Window Controls Overlay API. Installierte Desktop-Progressive-Web-Apps können damit eigene Inhalte in den Bereich zeichnen, in dem sonst die Titelleiste des Betriebssystems liegt. Die Fenstersteuerungen (Minimieren, Maximieren, Schließen) bleiben sichtbar und werden als Overlay über den Webinhalt gelegt. Die Instanz ist über navigator.windowControlsOverlay erreichbar.
Voraussetzung ist ein Eintrag im Web-App-Manifest: "display_override": ["window-controls-overlay"]. Außerdem muss die App installiert sein und in einem eigenen Fenster laufen. Wie eine klassische Titelleiste wird die Ansicht erst, wenn der Nutzer das Overlay über den Umschalter in der Titelleiste aktiviert.
Die Schnittstelle bietet:
visible(schreibgeschützt,boolean): gibt an, ob das Overlay gerade aktiv ist.getTitlebarAreaRect(): gibt einDOMRectmit Position und Größe des frei nutzbaren Titelleistenbereichs zurück.- Ereignis
geometrychange(bzw.ongeometrychange): wird ausgelöst, wenn sich die Sichtbarkeit oder Größe des Overlays ändert. Das Ereignisobjekt (WindowControlsOverlayGeometryChangeEvent) enthälttitlebarAreaRectundvisible.
Das Layout baut man in CSS meist mit den Umgebungsvariablen env(titlebar-area-x), env(titlebar-area-y), env(titlebar-area-width) und env(titlebar-area-height). Die JavaScript-Schnittstelle braucht man dann, wenn Logik von der Geometrie abhängt, zum Beispiel beim Ein- oder Ausblenden von Bedienelementen oder beim Wechsel zwischen einer kompakten und einer vollständigen Suchleiste.
Rückgabewert
navigator.windowControlsOverlay. In nicht unterstützenden Browsern ist der Wert undefined.Beispiele
Unterstützung prüfen und Geometrie auslesen
const wco = navigator.windowControlsOverlay;
if (wco) {
console.log('Overlay aktiv:', wco.visible);
const { x, y, width, height } = wco.getTitlebarAreaRect();
console.log(`Titelleistenbereich: x=${x}, y=${y}, ${width}×${height}`);
} else {
console.log('Window Controls Overlay wird nicht unterstützt.');
}
Auf Geometrieänderungen reagieren (mit Drosselung)
const wco = navigator.windowControlsOverlay;
const header = document.querySelector('#app-header');
const debounce = (fn, ms) => {
let t;
return (...args) => {
clearTimeout(t);
t = setTimeout(() => fn(...args), ms);
};
};
const onGeometryChange = debounce((event) => {
const { width } = event.titlebarAreaRect;
// Bei schmaler Titelleiste die kompakte Suche anzeigen
header.classList.toggle('compact', event.visible && width < 400);
header.classList.toggle('wco-active', event.visible);
}, 100);
wco?.addEventListener('geometrychange', onGeometryChange);
Event-Handler-Eigenschaft und Aufräumen
const wco = navigator.windowControlsOverlay;
const logChange = (e) => {
console.log('Sichtbar:', e.visible, 'Breite:', e.titlebarAreaRect.width);
};
if (wco) {
// Alternative zu addEventListener
wco.ongeometrychange = logChange;
// Später wieder entfernen
setTimeout(() => {
wco.ongeometrychange = null;
console.log('Handler entfernt');
}, 10_000);
}
Manifest und CSS zur Einrichtung (als JS-Objekt dargestellt)
// Ausschnitt aus manifest.webmanifest
const manifest = {
name: 'Meine PWA',
display: 'standalone',
display_override: ['window-controls-overlay'],
start_url: '/'
};
// Passendes CSS per JS einfügen
const style = document.createElement('style');
style.textContent = `
#app-header {
position: fixed;
left: env(titlebar-area-x, 0);
top: env(titlebar-area-y, 0);
width: env(titlebar-area-width, 100%);
height: env(titlebar-area-height, 40px);
-webkit-app-region: drag;
app-region: drag;
}
#app-header button, #app-header input { app-region: no-drag; }
`;
document.head.append(style);
console.log(manifest.display_override);
// Wichtig · Fallstricke
- Browser-Unterstützung: Nur Chromium-basierte Desktop-Browser (Chrome und Edge ab Version 105) unterstützen die API. Firefox, Safari und mobile Browser tun es nicht. Deshalb immer mit
navigator.windowControlsOverlay?auf Unterstützung prüfen. Die API funktioniert nur in einem sicheren Kontext (HTTPS). - Nur in installierten PWAs: Im normalen Browser-Tab ist
visibleimmerfalse, undgetTitlebarAreaRect()liefert ein leeres Rechteck (alle Werte0). - Das Overlay steuert der Nutzer: Die App kann das Overlay nicht per Skript aktivieren. Das Layout muss mit und ohne Overlay funktionieren. In CSS deshalb Ausweichwerte in
env()angeben. - Verschiebbare Bereiche: Ohne
app-region: drag(bzw.-webkit-app-region) kann der Nutzer das Fenster nicht mehr verschieben. Interaktive Elemente brauchenno-drag, sonst reagieren sie nicht auf Klicks. - Performance:
geometrychangekann beim Ändern der Fenstergröße sehr oft feuern. Handler daher drosseln (Debounce) und aufwendige Layout-Berechnungen vermeiden. - Sicherheit: Eigene Inhalte in der Titelleiste können Nutzer über die Herkunft der App täuschen, etwa wenn sie Browser-Elemente nachahmen. Chromium zeigt deshalb nach der Installation weiterhin Herkunftshinweise an. Die Titelleiste sollte nicht wie System- oder Browser-Oberfläche aussehen.