Mit der Screen Capture API kann der Nutzer einen Tab, ein Fenster oder einen Bildschirm auswählen, der als MediaStream erfasst werden soll. Dieser Stream kann dann aufgezeichnet oder über das Netzwerk für andere freigegeben werden. In dieser Dokumentation wird Conditional Focus vorgestellt, ein Mechanismus für Web-Apps, mit dem gesteuert werden kann, ob der erfasste Tab oder das erfasste Fenster beim Start der Erfassung in den Fokus gerückt wird oder ob die Erfassungsseite im Fokus bleibt.
Unterstützte Browser
Conditional Focus ist ab Chrome 109 verfügbar.
Hintergrund
Wenn eine Web-App einen Tab oder ein Fenster erfasst, muss der Browser entscheiden, ob die erfasste Oberfläche in den Vordergrund gerückt oder die Erfassungsseite im Fokus bleiben soll. Die Antwort hängt vom Grund für den Aufruf von getDisplayMedia() und von der Oberfläche ab, die der Nutzer auswählt.
Nehmen wir eine hypothetische Web-App für Videokonferenzen an. Durch Lesen von track.getSettings().displaySurface und möglicherweise durch Untersuchen des Erfassungshandles kann die Web-App für Videokonferenzen erkennen, was der Nutzer freigegeben hat. Dann:
- Wenn der erfasste Tab oder das erfasste Fenster per Fernzugriff gesteuert werden kann, bleibt die Videokonferenz im Vordergrund.
- Andernfalls wird der erfasste Tab oder das erfasste Fenster in den Fokus gerückt.
Im obigen Beispiel würde die Web-App für Videokonferenzen im Fokus bleiben, wenn eine Präsentation freigegeben wird, sodass der Nutzer die Folien per Fernzugriff durchblättern kann. Wenn der Nutzer jedoch einen Texteditor freigibt, würde die Web-App für Videokonferenzen sofort zum erfassten Tab oder Fenster wechseln.
Conditional Focus API verwenden
Instanziieren Sie ein CaptureController-Objekt und übergeben Sie es an getDisplayMedia(). Wenn Sie setFocusBehavior() sofort nach dem Auflösen des von getDiplayMedia() zurückgegebenen Promise aufrufen, können Sie steuern, ob der erfasste Tab oder das erfasste Fenster in den Fokus gerückt wird. Dies 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 der Fokus gesetzt werden soll, kann das Erfassungshandle berücksichtigt werden.
// 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");
}
Es ist sogar möglich, vor dem Aufruf von getDisplayMedia() zu entscheiden, ob der Fokus gesetzt werden soll.
// 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 aufrufen, bevor das Promise aufgelöst wird, oder höchstens einmal direkt nach dem Auflösen des Promise. Der letzte Aufruf überschreibt alle vorherigen Aufrufe.
Genauer gesagt:
- Das von
getDisplayMedia()zurückgegebene Versprechen wird für eine Mikrotask aufgelöst. Wenn SiesetFocusBehavior()aufrufen, nachdem diese Mikrotask abgeschlossen ist, wird ein Fehler ausgelöst. - Wenn Sie
setFocusBehavior()mehr als eine Sekunde nach Beginn der Erfassung aufrufen, hat das keine Auswirkungen.
Das heißt, beide der folgenden Snippets schlagen fehl:
// 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 auch in den folgenden Fällen einen Fehler aus:
- Die Videospur des von
getDisplayMedia()zurückgegebenen Streams ist nicht "live". - Nachdem das von
getDisplayMedia()zurückgegebene Promise aufgelöst wurde, wenn der Nutzer einen Bildschirm (nicht einen Tab oder ein Fenster) freigegeben hat.
Beispiel
Sie können Conditional Focus ausprobieren, indem Sie die Demo ausführen.
Funktionserkennung
Verwenden Sie Folgendes, um zu prüfen, 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.
Informationen zum Design
Funktioniert etwas an Conditional Focus nicht wie erwartet? Oder fehlen Methoden oder Eigenschaften, die Sie zur Umsetzung Ihrer Idee benötigen? Haben Sie eine Frage oder einen Kommentar zum Sicherheitsmodell?
- Melden Sie ein Problem mit der Spezifikation im GitHub-Repository oder fügen Sie Ihre Gedanken zu einem bestehenden Problem hinzu.
Problem mit der Implementierung?
Haben Sie einen Fehler in der Chrome-Implementierung gefunden? Oder unterscheidet sich die Implementierung von der Spezifikation?
- Melden Sie einen Fehler unter https://new.crbug.com. Geben Sie so viele Details wie möglich an und fügen Sie eine Anleitung zur Reproduktion hinzu.
Unterstützung zeigen
Planen Sie, Conditional Focus 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 einen Tweet an @ChromiumDev und teilen Sie uns mit, wo und wie Sie die Funktion verwenden.
Nützliche Links
Danksagungen
Vielen Dank an Rachel Andrew für die Überprüfung dieses Dokuments.