Mehrere Bildschirme mit der Window Management API verwalten

Sie können Informationen zu verbundenen Bildschirmen abrufen und Fenster relativ zu diesen Bildschirmen positionieren.

Fensterverwaltungs-API

Mit der Window Management API können Sie die mit Ihrem Computer verbundenen Displays auflisten. und Fenster auf bestimmten Bildschirmen zu platzieren.

Empfohlene Anwendungsfälle

Beispiele für Websites, die diese API verwenden können:

  • Mehrfenster-Grafikeditoren Gimp kann verschiedene in genau positionierten Fenstern.
  • Virtuelle Handelsplattformen können Markttrends in mehreren Fenstern anzeigen. Jedes davon kann in Vollbildmodus.
  • Mit Diashow-Apps können Vortragsnotizen auf dem internen Hauptbildschirm und die Präsentation auf einem externen Projektor.

Window Management API verwenden

Das Problem

Der bewährte Ansatz zur Steuerung von Fenstern, Window.open() ist leider und erkennt keine weiteren Bildschirme. Auch wenn einige Aspekte dieser API etwas veraltet erscheinen, wie die windowFeatures DOMString-Parameter hat sich trotzdem über die Jahre sehr gute Dienste erwiesen. Um die position haben, können Sie den Wert als left und top (oder screenX und screenY) und übergeben den gewünschten Wert Größe als width und height (oder innerWidth bzw. innerHeight). Um beispielsweise ein 400 × 300 50 Pixel von links und 50 Pixel von oben entfernt ist, ist dies der Code, könnte Folgendes enthalten:

const popup = window.open(
  'https://example.com/',
  'My Popup',
  'left=50,top=50,width=400,height=300',
);

Informationen zum aktuellen Bildschirm finden Sie auf der window.screen-Property, die gibt ein Screen-Objekt zurück. Dies ist die Ausgabe auf meinem MacBook Pro 13":

window.screen;
/* Output from my MacBook Pro 13″:
  availHeight: 969
  availLeft: 0
  availTop: 25
  availWidth: 1680
  colorDepth: 30
  height: 1050
  isExtended: true
  onchange: null
  orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null}
  pixelDepth: 30
  width: 1680
*/

Wie die meisten Menschen, die in der Technologiebranche arbeiten, musste ich mich an die neue Arbeitsumgebung anpassen und mein im Homeoffice arbeiten. Mein Foto sieht wie auf dem Foto unten aus (bei Interesse können Sie sich die genaue Details zu meiner Einrichtung) finden. Das iPad neben meinem MacBook ist über Sidecar: Bei Bedarf kann ich den Regler iPad in einen zweiten Bildschirm.

<ph type="x-smartling-placeholder">
</ph> Eine Schulbank auf zwei Stühlen. Oben auf der Schulbank befinden sich Schuhkartons, die einen Laptop und zwei iPads umgeben.
Eine Multiscreen-Einrichtung

Wenn ich den größeren Bildschirm nutzen möchte, kann ich das Pop-up Codebeispiel oben auf dem zweiten Bildschirm. Ich tue das. wie hier:

popup.moveTo(2500, 50);

Dies ist nur eine grobe Schätzung, da die Abmessungen des zweiten Bildschirms nicht bekannt sind. Informationen von window.screen deckt nur den integrierten Bildschirm ab, nicht aber den iPad-Bildschirm. Gemeldete width des integrierten Displays waren 1680 Pixel. Eine Bewegung von 2500 Pixeln kann dazu führen, dass sich der zum iPad wechseln, da ich zufällig weiß, dass es sich auf der rechten Seite meines MacBook befindet. Wie Kann ich das grundsätzlich tun? Es stellt sich heraus, dass es eine bessere Methode gibt, als zu raten. Auf diese Weise Window Management API

Funktionserkennung

So prüfen Sie, ob die Window Management API unterstützt wird:

if ('getScreenDetails' in window) {
  // The Window Management API is supported.
}

Die Berechtigung window-management

Bevor ich die Window Management API verwenden kann, muss ich den Nutzer um Erlaubnis bitten. Die Berechtigung window-management kann mit dem Permissions API so:

let granted = false;
try {
  const { state } = await navigator.permissions.query({ name: 'window-management' });
  granted = state === 'granted';
} catch {
  // Nothing.
}

Wenn Browser mit dem alten und dem neuen Berechtigungsnamen verwendet werden, musst du beim Anfordern der Berechtigung wie im Beispiel unten Verteidigungscode verwenden.

async function getWindowManagementPermissionState() {
  let state;
  // The new permission name.
  try {
    ({ state } = await navigator.permissions.query({
      name: "window-management",
    }));
  } catch (err) {
    return `${err.name}: ${err.message}`;
  }
  return state;
}

document.querySelector("button").addEventListener("click", async () => {
  const state = await getWindowManagementPermissionState();
  document.querySelector("pre").textContent = state;
});

Der Browser können die Berechtigungsaufforderung dynamisch beim ersten Versuch einer der Methoden des die neue API verwenden. Lesen Sie weiter, um zusätzliche Informationen zu erhalten!

Das Attribut window.screen.isExtended

Um herauszufinden, ob mehrere Bildschirme mit meinem Gerät verbunden sind, greife ich auf das window.screen.isExtended-Property. Sie gibt true oder false zurück. Bei meiner Einrichtung wird true zurückgegeben.

window.screen.isExtended;
// Returns `true` or `false`.

Die Methode getScreenDetails()

Jetzt, da ich weiß, dass die Multiscreen-Umgebung aktuell eingerichtet ist, kann ich weitere Informationen zur zweiten Bildschirm mit Window.getScreenDetails(). Beim Aufrufen dieser Funktion wird eine Berechtigungsaufforderung angezeigt, fragt mich, ob die Website sich öffnen und Fenster auf meinem Bildschirm platzieren darf. Die Funktion gibt ein Versprechen zurück, das mit einem ScreenDetailed-Objekt aufgelöst wird. Auf meinem MacBook Pro 13 mit einem verbundenen iPad enthält das Feld screens mit zwei ScreenDetailed-Objekten:

await window.getScreenDetails();
/* Output from my MacBook Pro 13″ with the iPad attached:
{
  currentScreen: ScreenDetailed {left: 0, top: 0, isPrimary: true, isInternal: true, devicePixelRatio: 2, …}
  oncurrentscreenchange: null
  onscreenschange: null
  screens: [{
    // The MacBook Pro
    availHeight: 969
    availLeft: 0
    availTop: 25
    availWidth: 1680
    colorDepth: 30
    devicePixelRatio: 2
    height: 1050
    isExtended: true
    isInternal: true
    isPrimary: true
    label: "Built-in Retina Display"
    left: 0
    onchange: null
    orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null}
    pixelDepth: 30
    top: 0
    width: 1680
  },
  {
    // The iPad
    availHeight: 999
    availLeft: 1680
    availTop: 25
    availWidth: 1366
    colorDepth: 24
    devicePixelRatio: 2
    height: 1024
    isExtended: true
    isInternal: false
    isPrimary: false
    label: "Sidecar Display (AirPlay)"
    left: 1680
    onchange: null
    orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null}
    pixelDepth: 24
    top: 0
    width: 1366
  }]
}
*/

Informationen zu den verbundenen Bildschirmen sind im screens-Array verfügbar. Beachten Sie, wie der Wert left für das iPad beginnt bei 1680, was genau dem width des integrierten Displays entspricht. Dieses kann ich genau bestimmen, wie die Bildschirme logisch angeordnet sind (nebeneinander, über sich gegenseitig usw.). Es gibt jetzt auch Daten für jeden Bildschirm, um zu zeigen, ob es sich um einen isInternal handelt und ob es sich um eine isPrimary handelt. Beachten Sie, dass der integrierte Bildschirm nicht unbedingt der primäre Bildschirm ist.

Das Feld currentScreen ist ein Live-Objekt, das dem aktuellen window.screen entspricht. Das -Objekt wird bei bildschirmübergreifenden Fensterplatzierungen oder bei Geräteänderungen aktualisiert.

Das screenschange-Ereignis

Das Einzige, was jetzt fehlt, ist eine Möglichkeit, zu erkennen, wenn sich meine Bildschirmeinrichtung ändert. Ein neues Ereignis, screenschange macht genau das: Es wird immer dann ausgelöst, wenn die Bildschirmkonstellation geändert wird. (Hinweis das „Filtert“ ist im Ereignisnamen die Pluralform.) Das bedeutet, dass das Ereignis immer dann ausgelöst wird, wenn ein neuer Bildschirm oder ein vorhandener Bildschirm (physisch oder virtuell im Fall von Sidecar) angeschlossen oder nicht verbunden ist.

Beachten Sie, dass Sie die neuen Bildschirmdetails asynchron abrufen müssen, das Ereignis screenschange. selbst diese Daten nicht zur Verfügung stellt. Verwenden Sie zum Suchen der Bildschirmdetails das Live-Objekt aus einem Cache-Speicher Screens-Schnittstelle.

const screenDetails = await window.getScreenDetails();
let cachedScreensLength = screenDetails.screens.length;
screenDetails.addEventListener('screenschange', (event) => {
  if (screenDetails.screens.length !== cachedScreensLength) {
    console.log(
      `The screen count changed from ${cachedScreensLength} to ${screenDetails.screens.length}`,
    );
    cachedScreensLength = screenDetails.screens.length;
  }
});

Das currentscreenchange-Ereignis

Wenn ich nur an Änderungen am aktuellen Bildschirm interessiert bin, d. h. am Wert des Live-Objekts, currentScreen) kann ich auf das currentscreenchange-Ereignis warten.

const screenDetails = await window.getScreenDetails();
screenDetails.addEventListener('currentscreenchange', async (event) => {
  const details = screenDetails.currentScreen;
  console.log('The current screen has changed.', event, details);
});

Das change-Ereignis

Wenn ich schließlich nur an Änderungen an einem konkreten Bildschirm interessiert bin, kann ich mir den change-Ereignis.

const firstScreen = (await window.getScreenDetails())[0];
firstScreen.addEventListener('change', async (event) => {
  console.log('The first screen has changed.', event, firstScreen);
});

Neue Vollbildoptionen

Bisher konnten Sie die Anzeige von Elementen im Vollbildmodus über den passend benannten requestFullScreen() . Die Methode verwendet einen options-Parameter, mit dem Sie FullscreenOptions Bisher ist ihre einzige Eigenschaft navigationUI Die Window Management API fügt die neue screen-Eigenschaft hinzu, mit der Sie bestimmen können, auf welchem Bildschirm der Vollbildmodus gestartet werden soll. Wenn Sie z. B. den primären Bildschirm Vollbild:

try {
  const primaryScreen = (await getScreenDetails()).screens.filter((screen) => screen.isPrimary)[0];
  await document.body.requestFullscreen({ screen: primaryScreen });
} catch (err) {
  console.error(err.name, err.message);
}

Polyfill

Es ist nicht möglich, die Window Management API mit Polyfill zu füllen, aber Sie können ihre Form so verändern, können Sie exklusiv für die neue API programmieren:

if (!('getScreenDetails' in window)) {
  // Returning a one-element array with the current screen,
  // noting that there might be more.
  window.getScreenDetails = async () => [window.screen];
  // Set to `false`, noting that this might be a lie.
  window.screen.isExtended = false;
}

Die anderen Aspekte der API, d. h. die verschiedenen Bildschirmänderungsereignisse und die Eigenschaft screen von das FullscreenOptions, würde einfach nie ausgelöst bzw. stillschweigend ignoriert werden. nicht unterstützten Browsern.

Demo

Wenn Sie etwas wie ich sind, behalten Sie die Entwicklung der verschiedenen Kryptowährungen. In Wirklichkeit tue ich das nicht, weil ich diesen Planeten liebe. nehmen wir einfach an, did.) Um den Überblick über meine Kryptowährungen zu behalten, habe ich eine Web-App entwickelt, mit der ich Ich beobachte die Märkte in allen Lebenssituationen, z. B. von meinem Bett aus, wo ich Single-Screen-Einrichtung.

<ph type="x-smartling-placeholder">
</ph> Riesiger Fernsehbildschirm am Ende eines Betts, auf dem die Beine der Schriftstellerin teilweise zu sehen sind. Auf dem Bildschirm ist eine Handelsplattform für Kryptowährungen zu sehen.
Märkte beobachten und entspannen.

Da es um Kryptowährungen geht, können die Märkte jederzeit hektisch werden. Sollte das passieren, kann ich gehe auf meinen Schreibtisch, wo ich die Multiscreen-Funktion eingerichtet habe. Ich kann auf das Fenster einer Währung klicken um schnell alle Details in einer Vollbildansicht auf dem gegenüberliegenden Bildschirm zu sehen. Unten sehen Sie ein aktuelles Foto von die ich während des letzten YCY-Blutbads genommen habe. Es hat mich gefangen und mich überrascht, mit meinen Händen im Gesicht.

<ph type="x-smartling-placeholder">
</ph> Der Autor blickt in Panik auf den Handel mit gefälschten Kryptowährungen und blickt in Panik.
In Panik, Zeuge des YCY-Blutbads.

Du kannst mit der unten eingebetteten Demo spielen oder den Quellcode bei einer Störung ansehen.

Sicherheit und Berechtigungen

Das Chrome-Team hat die Window Management API mithilfe der zentralen die unter Zugriff auf leistungsstarke Webplattform-Funktionen steuern erläutert wird, einschließlich Nutzersteuerung, Transparenz und Ergonomie. Die Window Management API stellt Informationen neue Informationen über die mit einem Gerät verbundenen Bildschirme, wodurch sich die Fingerprinting-Oberfläche insbesondere Nutzer mit mehreren Bildschirmen, die ständig mit ihren Geräten verbunden sind. Als eine Um diese Datenschutzbedenken zu umgehen, sind die Eigenschaften des sichtbaren Displays auf das erforderliche Minimum beschränkt. für häufige Placement-Anwendungsfälle. Für Websites ist eine Nutzerberechtigung erforderlich, um Multiscreen-Websites anzeigen zu lassen und Fenster auf anderen Bildschirmen platzieren. Chromium gibt zwar detaillierte Bildschirmlabels zurück, können Browser weniger beschreibende (oder sogar leere Labels) zurückgeben.

Nutzersteuerung

Der Nutzer hat die volle Kontrolle über die Präsenz seiner Einrichtung. Er kann die Nutzungsbedingungen annehmen oder ablehnen. und Widerrufen einer zuvor erteilten Berechtigung über die Funktion „Websiteinformationen“ in im Browser.

Kontrolle für Unternehmen

Chrome Enterprise-Nutzer können verschiedene Aspekte der Window Management API steuern, indem sie die im entsprechenden Abschnitt des Atomare Richtliniengruppen Einstellungen.

Transparenz

Die Tatsache, ob die Berechtigung zur Verwendung der Window Management API gewährt wurde, ist in den Website-Informationen des Browsers angezeigt und kann auch über die Permissions API abgefragt werden.

Berechtigungstreue

Der Browser behält die erteilten Berechtigungen bei. Die Berechtigung kann über die Website des Browsers widerrufen werden. Informationen.

Feedback

Das Chrome-Team möchte mehr über Ihre Erfahrungen mit der Window Management API wissen.

Informationen zum API-Design

Gibt es etwas an der API, das nicht wie erwartet funktioniert? Oder fehlen Methoden, oder Eigenschaften, die Sie für die Umsetzung Ihrer Idee benötigen? Fragen oder Kommentare zur Sicherheit haben Modell?

  • Reichen Sie ein Spezifikationsproblem im entsprechenden GitHub-Repository ein oder fügen Sie Ihre Gedanken zu einem vorhandenen Repository hinzu. Problem.

Problem mit der Implementierung melden

Haben Sie bei der Implementierung von Chrome einen Fehler gefunden? Oder weicht die Implementierung von der Spezifikation ab?

  • Melde einen Fehler unter new.crbug.com. Achten Sie darauf, so viele Details wie und eine einfache Anleitung zum Reproduzieren. Geben Sie Blink>Screen>MultiScreen in das Feld Komponenten. Glitch eignet sich hervorragend, um schnelle und einfache Reproduktionen zu teilen.

Unterstützung für die API anzeigen

Möchten Sie die Window Management API verwenden? Ihre öffentliche Unterstützung hilft der Chrome- , um Funktionen zu priorisieren und anderen Browseranbietern zu zeigen, wie wichtig es für ihre Unterstützung ist.

  • Im WICG Discourse-Thread können Sie uns mitteilen, wie Sie den Dienst verwenden möchten.
  • Sende einen Tweet mit dem Hashtag an @ChromiumDev #WindowManagement und lassen Sie uns wissen, wo und wie Sie sie verwenden.
  • Bitten Sie andere Browseranbieter, die API zu implementieren.

Nützliche Links

Danksagungen

Die Window Management API-Spezifikation wurde bearbeitet von Victor Costan Joshua Bell und Michael Wasserman Die API wurde von Mike Wasserman und Adrienne Walker: Artikel wurde geprüft von Joe Medley, François Beaufort, und Kayce Basques. Vielen Dank an Laura Torrent Puig für die Fotos.