Beter scherm delen met voorwaardelijke focus

François Beaufort
François Beaufort

Browserondersteuning

  • Chroom: 109.
  • Rand: 109.
  • Firefox: niet ondersteund.
  • Safari: niet ondersteund.

Bron

Met de Screen Capture API kan de gebruiker een tabblad, venster of scherm selecteren om vast te leggen als mediastream. Deze stream kan vervolgens via het netwerk worden opgenomen of met anderen worden gedeeld. Deze documentatie introduceert Voorwaardelijke focus, een mechanisme waarmee webapps kunnen bepalen of het vastgelegde tabblad of venster de focus krijgt wanneer het vastleggen begint, of dat de vastgelegde pagina gefocust blijft.

Browser-ondersteuning

Voorwaardelijke focus is beschikbaar vanaf Chrome 109.

Achtergrond

Wanneer een webapp een tabblad of venster begint vast te leggen, staat de browser voor een beslissing: moet het vastgelegde oppervlak naar de voorgrond worden gebracht, of moet de vastgelegde pagina gefocust blijven? Het antwoord hangt af van de reden voor het aanroepen getDisplayMedia() en van het oppervlak dat de gebruiker uiteindelijk selecteert.

Overweeg een hypothetische webapp voor videoconferenties. Door track.getSettings().displaySurface te lezen en mogelijk de Capture Handle te onderzoeken, kan de webapp voor videoconferenties begrijpen wat de gebruiker wil delen. Dan:

  • Als het vastgelegde tabblad of venster op afstand kan worden bediend, houdt u de videoconferentie scherp.
  • Anders stelt u scherp op het vastgelegde tabblad of venster.

In het bovenstaande voorbeeld behoudt de webapp voor videoconferenties de focus bij het delen van een diaserie, waardoor de gebruiker op afstand door de dia's kan bladeren; maar als de gebruiker ervoor kiest een teksteditor te delen, verschuift de webapp voor videoconferenties onmiddellijk de focus naar het vastgelegde tabblad of venster.

Met behulp van de Conditionele Focus-API

Instantieer een CaptureController en geef deze door aan getDisplayMedia() . Door setFocusBehavior() aan te roepen onmiddellijk nadat de geretourneerde getDiplayMedia() -belofte is opgelost, kunt u bepalen of het vastgelegde tabblad of venster de focus krijgt of niet. Dit kan alleen worden gedaan als de gebruiker een tabblad of venster heeft gedeeld.

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");
}

Bij de beslissing of er moet worden scherpgesteld, kan rekening worden gehouden met de Capture Handle .

// 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");
}

Het is zelfs mogelijk om te beslissen of u wilt focussen voordat u getDisplayMedia() aanroept.

// 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 });

U kunt setFocusBehavior() vele malen willekeurig aanroepen voordat de belofte wordt opgelost, of hoogstens één keer onmiddellijk nadat de belofte is opgelost. De laatste aanroep overschrijft alle voorgaande aanroepen.

Nauwkeuriger: - De geretourneerde belofte getDisplayMedia() wordt omgezet in een microtaak. Het aanroepen van setFocusBehavior() nadat de microtaak is voltooid, levert een fout op. - Het aanroepen van setFocusBehavior() meer dan een seconde nadat het vastleggen is gestart, is niet mogelijk.

Dat wil zeggen dat beide volgende fragmenten mislukken:

// 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");

Het aanroepen van setFocusBehavior() levert ook in de volgende gevallen op:

  • de videotrack van de stream die wordt geretourneerd door getDisplayMedia() is niet "live" .
  • nadat de getDisplayMedia() geretourneerde belofte is opgelost, als de gebruiker een scherm heeft gedeeld (geen tabblad of venster).

Steekproef

Je kunt met Conditional Focus spelen door de demo op Glitch uit te voeren. Zorg ervoor dat u de broncode bekijkt .

Functiedetectie

Om te controleren of CaptureController.setFocusBehavior() wordt ondersteund, gebruikt u:

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

Feedback

Het Chrome-team en de webstandaardgemeenschap willen graag horen over uw ervaringen met Voorwaardelijke focus.

Vertel ons over het ontwerp

Is er iets aan voorwaardelijke focus dat niet werkt zoals je had verwacht? Of ontbreken er methoden of eigenschappen die je nodig hebt om je idee te implementeren? Heeft u een vraag of opmerking over het beveiligingsmodel?

  • Dien een spec-probleem in op de GitHub-repository of voeg uw mening toe aan een bestaand probleem.

Probleem met de implementatie?

Heeft u een bug gevonden in de implementatie van Chrome? Of wijkt de uitvoering af van de specificaties?

  • Dien een bug in op https://new.crbug.com . Zorg ervoor dat u zoveel mogelijk details en eenvoudige reproductie-instructies opneemt. Glitch werkt goed voor het delen van code.

Toon steun

Ben je van plan gebruik te maken van Voorwaardelijke Focus? Uw publieke steun helpt het Chrome-team prioriteiten te stellen voor functies en laat andere browserleveranciers zien hoe belangrijk het is om deze te ondersteunen.

Stuur een tweet naar @ChromiumDev en laat ons weten waar en hoe je het gebruikt.

Dankbetuigingen

Heldenafbeelding door Elena Taranenko .

Met dank aan Rachel Andrew voor het beoordelen van dit artikel.