Bessere Bildschirmfreigabe dank bedingtem Fokus

François Beaufort
François Beaufort

Unterstützte Browser

  • Chrome: 109.
  • Edge: 109.
  • Firefox: Nicht unterstützt.
  • Safari: Nicht unterstützt.

Quelle

Mit der Screen Capture API kann der Nutzer einen Tab, ein Fenster oder einen Bildschirm auswählen, der als Medienstream erfasst werden soll. Dieser Stream kann dann aufgezeichnet oder über das Netzwerk mit anderen geteilt werden. In dieser Dokumentation wird der bedingte Fokus vorgestellt, ein Mechanismus für Web-Apps, mit dem gesteuert wird, ob der erfasste Tab oder das erfasste Fenster zu Beginn der Erfassung fokussiert wird oder ob die Erfassungsseite fokussiert bleiben soll.

Unterstützte Browser

Der bedingte Fokus ist seit Chrome 109 verfügbar.

Hintergrund

Wenn eine Webanwendung mit der Erfassung eines Tabs oder Fensters beginnt, muss der Browser eine Entscheidung treffen: Soll die erfasste Oberfläche in den Vordergrund gebracht werden oder soll der Fokus auf der Seite bleiben, die erfasst wird? Die Antwort hängt davon ab, warum getDisplayMedia() aufgerufen wurde, und von der Oberfläche, die der Nutzer auswählt.

Stellen Sie sich eine hypothetische Webanwendung für Videokonferenzen vor. Wenn die Webanwendung track.getSettings().displaySurface liest und gegebenenfalls den Capture Handle untersucht, kann sie erkennen, was der Nutzer freigegeben hat. Dann:

  • Wenn der Tab oder das Fenster, das aufgenommen wird, per Fernzugriff gesteuert werden kann, halten Sie die Videokonferenz im Fokus.
  • Andernfalls setzen Sie den Fokus auf den erfassten Tab oder das aufgenommene Fenster.

Im Beispiel oben würde die Web-App für Videokonferenzen den Fokus bei der Freigabe einer Präsentation beibehalten, sodass der Nutzer die Folien aus der Ferne durchblättern kann. Wenn der Nutzer jedoch einen Texteditor freigibt, wechselt die Web-App für Videokonferenzen sofort den Fokus zum aufgenommenen Tab oder Fenster.

Conditional Focus API verwenden

Instanziere eine CaptureController und übergebe sie an getDisplayMedia(). Wenn Sie setFocusBehavior() sofort nach der Auflösung des zurückgegebenen Versprechens getDiplayMedia() aufrufen, können Sie festlegen, ob der erfasste Tab oder das erfasste Fenster den Fokus erhält oder nicht. Das ist nur möglich, wenn der Nutzer einen Tab oder ein Fenster freigegeben hat.

const controller = new CaptureController();

// Prompt the user to share a tab, a window or a screen.
const stream =
    await navigator.mediaDevices.getDisplayMedia({ controller });

const [track] = stream.getVideoTracks();
const displaySurface = track.getSettings().displaySurface;
if (displaySurface == "browser") {
  // Focus the captured tab.
  controller.setFocusBehavior("focus-captured-surface");
} else if (displaySurface == "window") {
  // Do not move focus to the captured window.
  // Keep the capturing page focused.
  controller.setFocusBehavior("focus-capturing-application");
}

Bei der Entscheidung, ob Sie den Fokus festlegen möchten, können Sie den Capture-Griff berücksichtigen.

// Retain focus if capturing a tab dialed to example.com.
// Focus anything else.
const origin = track.getCaptureHandle().origin;
if (displaySurface == "browser" && origin == "https://example.com") {
  controller.setFocusBehavior("focus-capturing-application");
} else if (displaySurface != "monitor") {
  controller.setFocusBehavior("focus-captured-surface");
}

Sie können sogar festlegen, ob Sie sich konzentrieren möchten, bevor Sie getDisplayMedia() aufrufen.

// Focus the captured tab or window when capture starts.
const controller = new CaptureController();
controller.setFocusBehavior("focus-captured-surface");

// Prompt the user to share their screen.
const stream =
    await navigator.mediaDevices.getDisplayMedia({ controller });

Sie können setFocusBehavior() beliebig oft vor oder höchstens einmal direkt nach der Auflösung des Versprechens aufrufen. Die letzte Aufrufe überschreibt alle vorherigen Aufrufe.

Genauer gesagt: – Das von getDisplayMedia() zurückgegebene Versprechen wird in einem Mikrotask aufgelöst. Wenn setFocusBehavior() nach Abschluss dieses Microtasks aufgerufen wird, wird ein Fehler ausgegeben. – Wenn setFocusBehavior() mehr als eine Sekunde nach Beginn der Erfassung aufgerufen wird, hat das keine Auswirkungen.

Das bedeutet, dass beide folgenden Snippets fehlschlagen:

// Prompt the user to share their screen.
const stream =
    await navigator.mediaDevices.getDisplayMedia({ controller });

// Too late, because it follows the completion of the task
// on which the getDisplayMedia() promise resolved.
// This will throw.
setTimeout(() => {
  controller.setFocusBehavior("focus-captured-surface");
});
// Prompt the user to share their screen.
const stream =
    await navigator.mediaDevices.getDisplayMedia({ controller });

const start = new Date();
while (new Date() - start <= 1000) {
  // Idle for ≈1s.
}

// Because too much time has elapsed, the browser will have
// already decided whether to focus.
// This fails silently.
controller.setFocusBehavior("focus-captured-surface");

Der Aufruf von setFocusBehavior() löst außerdem in den folgenden Fällen aus:

  • der Videotrack des von getDisplayMedia() zurückgegebenen Streams nicht „live“ ist.
  • nach der Auflösung des zurückgegebenen Promises von getDisplayMedia(), wenn der Nutzer einen Bildschirm (keinen Tab oder ein Fenster) geteilt hat.

Beispiel

Sie können mit dem bedingten Fokus experimentieren, indem Sie die Demo auf Glitch ausführen. Sehen Sie sich den Quellcode an.

Funktionserkennung

So prüfen Sie, ob CaptureController.setFocusBehavior() unterstützt wird:

if (
  "CaptureController" in window &&
  "setFocusBehavior" in CaptureController.prototype
) {
  // CaptureController.setFocusBehavior() is supported.
}

Feedback

Das Chrome-Team und die Webstandards-Community möchten mehr über Ihre Erfahrungen mit Conditional Focus erfahren.

Designbeschreibung

Funktioniert der bedingte Fokus nicht wie erwartet? Oder fehlen Methoden oder Eigenschaften, die du zur Umsetzung deiner Idee benötigst? Haben Sie Fragen oder Kommentare zum Sicherheitsmodell?

  • Melden Sie ein Problem mit der Spezifikation im GitHub-Repository oder fügen Sie Ihre Gedanken zu einem vorhandenen Problem hinzu.

Problem bei der Implementierung?

Haben Sie einen Fehler in der Chrome-Implementierung gefunden? Oder unterscheidet sich die Implementierung von der Spezifikation?

  • Melden Sie den Fehler unter https://new.crbug.com. Geben Sie dabei so viele Details wie möglich an und machen Sie eine einfache Anleitung zur Reproduktion. Glitch eignet sich gut zum Teilen von Code.

Unterstützung zeigen

Planen Sie, den bedingten Fokus zu verwenden? Ihre öffentliche Unterstützung hilft dem Chrome-Team, Funktionen zu priorisieren, und zeigt anderen Browseranbietern, wie wichtig es ist, sie zu unterstützen.

Senden Sie uns einen Tweet an @ChromiumDev und teilen Sie uns mit, wo und wie Sie es verwenden.

Danksagungen

Hero-Image von Elena Taranenko.

Vielen Dank an Rachel Andrew für die Überprüfung dieses Artikels.