Condivisione schermo migliorata con la funzionalità Conditional Focus

François Beaufort
François Beaufort

Supporto dei browser

  • Chrome: 109.
  • Edge: 109.
  • Firefox: non supportato.
  • Safari: non supportato.

Origine

L'API Screen Capture consente all'utente di selezionare una scheda, una finestra o una schermata da acquisire come stream multimediale. Questo stream può quindi essere registrato o condiviso con altri utenti sulla rete. Questa documentazione introduce l'impostazione dello stato attivo condizionale, un meccanismo che consente alle app web di controllare se lo stato attivo della scheda o della finestra acquisita viene attivato all'avvio dell'acquisizione o se lo stato rimane attivo per la pagina di acquisizione.

Supporto browser

L'attenzione condizionale è disponibile nella versione 109 di Chrome.

Sfondo

Quando un'app web inizia ad acquisire una scheda o una finestra, il browser deve prendere una decisione: l'area acquisita deve essere messa in primo piano o la pagina di acquisizione deve rimanere in primo piano? La risposta dipende dal motivo della chiamata a getDisplayMedia() e dalla piattaforma che l'utente dovrà selezionare.

Prendi in considerazione un'app web per videoconferenze ipotetica. Leggendo track.getSettings().displaySurface e potenzialmente esaminando l'handle di acquisizione, l'app web per videoconferenze può capire cosa l'utente ha scelto di condividere. Quindi:

  • Se la scheda o la finestra acquisita possono essere controllate da remoto, mantieni lo stato attivo della videoconferenza.
  • In caso contrario, imposta lo stato attivo sulla scheda o sulla finestra acquisita.

Nell'esempio precedente, l'app web per videoconferenze manterrà l'attenzione se condivide una presentazione, consentendo all'utente di scorrere da remoto le slide. ma se l'utente scegliesse di condividere un editor di testo, l'app web per videoconferenze passerà immediatamente allo stato attivo sulla scheda o sulla finestra acquisita.

Utilizzo dell'API Conditional Focus

Crea un'istanza di CaptureController e passala a getDisplayMedia(). Chiamando setFocusBehavior() subito dopo la risoluzione della promessa restituita da getDiplayMedia(), puoi controllare se lo stato attivo della scheda o della finestra acquisita verrà o meno. Questa operazione può essere eseguita solo se l'utente ha condiviso una scheda o una finestra.

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

Per decidere se concentrarsi, è possibile prendere in considerazione l'handle di acquisizione.

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

Puoi persino decidere se concentrarti prima di chiamare il numero getDisplayMedia().

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

Puoi chiamare setFocusBehavior() arbitrariamente molte volte prima della risoluzione della promessa o al massimo una volta subito dopo la risoluzione della promessa. L'ultima chiamata sostituisce tutte le chiamate precedenti.

Più precisamente: - La promessa restituita getDisplayMedia() si risolve in un microattività. Chiamare setFocusBehavior() al termine della microattività genera un errore. - Chiamare setFocusBehavior() più di un secondo dopo l'avvio dell'acquisizione è autonomo.

In altre parole, entrambi i seguenti snippet non riusciranno:

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

La chiamata a setFocusBehavior() comporta anche i seguenti casi:

  • la traccia video dello stream restituito da getDisplayMedia() non è "live".
  • dopo la risoluzione della promessa restituita da getDisplayMedia(), se l'utente ha condiviso una schermata (non una scheda o una finestra).

Esempio

Puoi giocare con la messa a fuoco condizionale eseguendo la demo su Glitch. Assicurati di controllare il codice sorgente.

Rilevamento delle caratteristiche

Per verificare se CaptureController.setFocusBehavior() è supportato, usa:

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

Feedback

Il team di Chrome e la community degli standard web vogliono conoscere la tua esperienza con l'attenzione condizionale.

Parlaci del design

C'è qualcosa della messa a fuoco condizionale che non funziona come ti aspettavi? Oppure mancano metodi o proprietà che ti servono per implementare la tua idea? Hai una domanda o un commento sul modello di sicurezza?

  • Segnala un problema relativo alle specifiche sul repository GitHub o aggiungi le tue opinioni a un problema esistente.

Problemi con l'implementazione?

Hai trovato un bug nell'implementazione di Chrome? Oppure l'implementazione è diversa dalle specifiche?

Mostra il tuo sostegno

Hai intenzione di utilizzare la messa a fuoco condizionale? Il supporto pubblico aiuta il team di Chrome a dare priorità alle funzionalità e mostra agli altri fornitori di browser quanto sia fondamentale supportarle.

Invia un tweet a @ChromiumDev e facci sapere dove e come lo utilizzi.

Ringraziamenti

Immagine hero di Elena Taranenko.

Grazie a Rachel Andrew per aver letto questo articolo.