Condivisione schermo migliorata con la funzionalità Conditional Focus

François Beaufort
François Beaufort

Browser Support

  • Chrome: 109.
  • Edge: 109.
  • Firefox: not supported.
  • Safari: not supported.

Source

L'API Screen Capture consente all'utente di selezionare una scheda, una finestra o uno schermo da acquisire come flusso multimediale. Questo flusso può essere registrato o condiviso con altri utenti tramite la rete. Questa documentazione introduce Conditional Focus, un meccanismo per le app web che consente di controllare se la scheda o la finestra acquisita verrà messa a fuoco all'avvio dell'acquisizione o se la pagina di acquisizione rimarrà a fuoco.

Supporto browser

Conditional Focus è disponibile a partire da Chrome 109.

Sfondo

Quando un'app web inizia ad acquisire una scheda o una finestra, il browser deve prendere una decisione: la superficie acquisita deve essere portata in primo piano o la pagina di acquisizione deve rimanere a fuoco? La risposta dipende dal motivo della chiamata a getDisplayMedia() e dalla superficie selezionata dall'utente.

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

  • Se la scheda o la finestra acquisita può essere controllata da remoto, mantieni la videoconferenza a fuoco.
  • In caso contrario, metti a fuoco la scheda o la finestra acquisita.

Nell'esempio precedente, l'app web di videoconferenza manterrebbe lo stato attivo se condividesse una presentazione diapositive, consentendo all'utente di sfogliare le diapositive da remoto; tuttavia, se l'utente scegliesse di condividere un editor di testo, l'app web di videoconferenza passerebbe immediatamente lo stato attivo alla scheda o alla finestra acquisita.

Utilizzo dell'API Conditional Focus

Crea un'istanza di CaptureController e passala a getDisplayMedia(). Chiamando setFocusBehavior() immediatamente dopo la risoluzione della promessa restituita da getDiplayMedia(), puoi controllare se la scheda o la finestra acquisita verrà messa a fuoco 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");
}

Quando decidi se mettere a fuoco, puoi 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");
}

È anche possibile decidere se mettere a fuoco prima di chiamare 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() un numero arbitrario di volte prima che la promessa venga risolta o al massimo una volta immediatamente dopo la risoluzione della promessa. L'ultima chiamata sostituisce tutte le chiamate precedenti.

Più precisamente:

  • La promessa restituita da getDisplayMedia() viene risolta in un microtask. La chiamata a setFocusBehavior() dopo il completamento del microtask genera un errore.
  • La chiamata a setFocusBehavior() più di un secondo dopo l'avvio dell'acquisizione è un'operazione senza effetto.

Ovvero, entrambi gli snippet seguenti non andranno a buon fine:

// 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() genera anche un'eccezione nei seguenti casi:

  • La traccia video del flusso restituito da getDisplayMedia() non è "live".
  • Dopo la risoluzione della promessa restituita da getDisplayMedia(), se l'utente ha condiviso uno schermo (non una scheda o una finestra).

Esempio

Puoi sperimentare Conditional Focus eseguendo la demo.

Presentazione della funzionalità

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

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 le tue esperienze con Conditional Focus.

Parlaci del design

C'è qualcosa in Conditional Focus che non funziona come previsto? Oppure mancano metodi o proprietà di cui hai bisogno per implementare la tua idea? Hai una domanda o un commento sul modello di sicurezza?

  • Invia una segnalazione relativa alle specifiche nel repository GitHub o aggiungi i tuoi pensieri a una segnalazione esistente.

Problemi con l'implementazione?

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

  • Invia un bug all'indirizzo https://new.crbug.com. Assicurati di includere il maggior numero di dettagli possibile e le istruzioni per la riproduzione.

Mostra il tuo sostegno

Hai intenzione di utilizzare Conditional Focus? Il tuo sostegno pubblico aiuta il team di Chrome a dare la priorità alle funzionalità e mostra ad altri fornitori di browser quanto sia fondamentale supportarle.

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

Ringraziamenti

Grazie a Rachel Andrew per aver esaminato questo documento.