Ottenere informazioni sui display collegati e posizionare le finestre rispetto a questi display.
API Window Management
L'API Window Management consente di enumerare i display collegati alla macchina e di posizionare le finestre su schermi specifici.
Casi d'uso suggeriti
Ecco alcuni esempi di siti che potrebbero utilizzare questa API:
- Gli editor grafici multi-finestra come Gimp possono posizionare vari strumenti di modifica in finestre posizionate con precisione.
- Le sale di contrattazione virtuali possono mostrare le tendenze di mercato in più finestre, ognuna delle quali può essere visualizzata in modalità a schermo intero.
- Le app di presentazione possono mostrare le note del relatore sullo schermo principale interno e la presentazione su un proiettore esterno.
Come utilizzare l'API Window Management
Il problema
L'approccio collaudato al controllo delle finestre,
Window.open()
, purtroppo
non rileva schermi aggiuntivi. Sebbene alcuni aspetti di questa API sembrino un po' arcaici, come il parametro
windowFeatures
DOMString
, ci ha comunque servito bene nel corso degli anni. Per specificare la
posizione di una finestra, puoi passare le
coordinate come left
e top
(o screenX
e screenY
rispettivamente) e passare le
dimensioni desiderate come
width
e height
(o innerWidth
e innerHeight
rispettivamente). Ad esempio, per aprire una finestra
400×300 a 50 pixel da sinistra e 50 pixel dall'alto, puoi utilizzare questo codice:
const popup = window.open(
'https://example.com/',
'My Popup',
'left=50,top=50,width=400,height=300',
);
Puoi ottenere informazioni sulla schermata corrente esaminando la proprietà
window.screen
, che
restituisce un oggetto Screen
. Questo è l'output
sul mio MacBook Pro 13":
window.screen;
/* Output from my MacBook Pro 13″:
availHeight: 969
availLeft: 0
availTop: 25
availWidth: 1680
colorDepth: 30
height: 1050
isExtended: true
onchange: null
orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null}
pixelDepth: 30
width: 1680
*/
Come la maggior parte delle persone che lavorano nel settore tecnologico, ho dovuto adattarmi alla nuova realtà lavorativa e allestire il mio ufficio personale in casa. Il mio è simile a quello nella foto qui sotto (se ti interessa, puoi leggere i dettagli completi della mia configurazione). L'iPad accanto al mio MacBook è connesso al laptop tramite Sidecar, quindi quando ne ho bisogno posso trasformare rapidamente l'iPad in un secondo schermo.

Se voglio sfruttare lo schermo più grande, posso spostare il popup dell'esempio di codice riportato sopra sul secondo schermo. Io lo faccio così:
popup.moveTo(2500, 50);
Si tratta di una stima approssimativa, poiché non è possibile conoscere le dimensioni del secondo schermo. Le informazioni
di window.screen
riguardano solo lo schermo integrato, non quello dell'iPad. La width
segnalata dello schermo integrato era di 1680
pixel, quindi passare a 2500
pixel potrebbe funzionare per spostare la
finestra sull'iPad, dato che so che si trova a destra del mio MacBook. Come
posso farlo nel caso generale? A quanto pare, esiste un modo migliore per evitare di tirare a indovinare. Questo modo è l'API
Window Management.
Rilevamento delle funzionalità
Per verificare se l'API Window Management è supportata, utilizza:
if ('getScreenDetails' in window) {
// The Window Management API is supported.
}
L'autorizzazione window-management
Prima di poter utilizzare l'API Window Management, devo chiedere all'utente l'autorizzazione per farlo.
L'autorizzazione window-management
può essere richiesta con l'API Permissions nel seguente modo:
let granted = false;
try {
const { state } = await navigator.permissions.query({ name: 'window-management' });
granted = state === 'granted';
} catch {
// Nothing.
}
Mentre sono in uso browser con il nome dell'autorizzazione precedente e quello nuovo, assicurati di utilizzare un codice difensivo quando richiedi l'autorizzazione, come nell'esempio riportato di seguito.
async function getWindowManagementPermissionState() {
let state;
// The new permission name.
try {
({ state } = await navigator.permissions.query({
name: "window-management",
}));
} catch (err) {
return `${err.name}: ${err.message}`;
}
return state;
}
document.querySelector("button").addEventListener("click", async () => {
const state = await getWindowManagementPermissionState();
document.querySelector("pre").textContent = state;
});
Il browser può scegliere di mostrare la richiesta di autorizzazione in modo dinamico al primo tentativo di utilizzare uno dei metodi della nuova API. Per saperne di più, continua a leggere quanto segue.
Proprietà window.screen.isExtended
Per scoprire se al mio dispositivo è collegato più di uno schermo, accedo alla proprietà
window.screen.isExtended
. Restituisce true
o false
. Per la mia configurazione, restituisce true
.
window.screen.isExtended;
// Returns `true` or `false`.
Il metodo getScreenDetails()
Ora che so che la configurazione attuale è multi-schermo, posso ottenere maggiori informazioni sul
secondo schermo utilizzando Window.getScreenDetails()
. Se chiamo questa funzione, viene visualizzata una richiesta di autorizzazione che
mi chiede se il sito può aprire e posizionare finestre sullo schermo. La funzione restituisce una promessa
che viene risolta con un oggetto ScreenDetailed
. Sul mio MacBook Pro 13 con un iPad connesso,
è incluso un campo screens
con due oggetti ScreenDetailed
:
await window.getScreenDetails();
/* Output from my MacBook Pro 13″ with the iPad attached:
{
currentScreen: ScreenDetailed {left: 0, top: 0, isPrimary: true, isInternal: true, devicePixelRatio: 2, …}
oncurrentscreenchange: null
onscreenschange: null
screens: [{
// The MacBook Pro
availHeight: 969
availLeft: 0
availTop: 25
availWidth: 1680
colorDepth: 30
devicePixelRatio: 2
height: 1050
isExtended: true
isInternal: true
isPrimary: true
label: "Built-in Retina Display"
left: 0
onchange: null
orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null}
pixelDepth: 30
top: 0
width: 1680
},
{
// The iPad
availHeight: 999
availLeft: 1680
availTop: 25
availWidth: 1366
colorDepth: 24
devicePixelRatio: 2
height: 1024
isExtended: true
isInternal: false
isPrimary: false
label: "Sidecar Display (AirPlay)"
left: 1680
onchange: null
orientation: ScreenOrientation {angle: 0, type: "landscape-primary", onchange: null}
pixelDepth: 24
top: 0
width: 1366
}]
}
*/
Le informazioni sugli schermi collegati sono disponibili nell'array screens
. Nota come il valore di
left
per l'iPad inizia da 1680
, che corrisponde esattamente a width
del display integrato. In questo modo
posso determinare esattamente come sono disposti logicamente gli schermi (uno accanto all'altro, uno sopra
l'altro e così via). Ora sono disponibili anche i dati per ogni schermata per mostrare se si tratta di una schermata isInternal
e se si tratta di una schermata isPrimary
. Tieni presente che lo schermo integrato
non è necessariamente lo schermo principale.
Il campo currentScreen
è un oggetto attivo corrispondente all'window.screen
corrente. L'oggetto
viene aggiornato nei posizionamenti delle finestre cross-screen o nelle modifiche del dispositivo.
L'evento screenschange
L'unica cosa che manca ora è un modo per rilevare quando cambia la configurazione dello schermo. Un nuovo evento,
screenschange
, fa esattamente questo: si attiva ogni volta che la costellazione dello schermo viene modificata. (Tieni presente
che "screens" è al plurale nel nome dell'evento.) Ciò significa che l'evento viene attivato ogni volta che una nuova schermata o una schermata esistente viene (fisicamente o virtualmente nel caso di Sidecar) collegata o scollegata.
Tieni presente che devi cercare i dettagli della nuova schermata in modo asincrono, l'evento screenschange
stesso non fornisce questi dati. Per cercare i dettagli dello schermo, utilizza l'oggetto live da un'interfaccia Screens
memorizzata nella cache.
const screenDetails = await window.getScreenDetails();
let cachedScreensLength = screenDetails.screens.length;
screenDetails.addEventListener('screenschange', (event) => {
if (screenDetails.screens.length !== cachedScreensLength) {
console.log(
`The screen count changed from ${cachedScreensLength} to ${screenDetails.screens.length}`,
);
cachedScreensLength = screenDetails.screens.length;
}
});
L'evento currentscreenchange
Se mi interessano solo le modifiche alla schermata corrente (ovvero il valore dell'oggetto live currentScreen
), posso ascoltare l'evento currentscreenchange
.
const screenDetails = await window.getScreenDetails();
screenDetails.addEventListener('currentscreenchange', async (event) => {
const details = screenDetails.currentScreen;
console.log('The current screen has changed.', event, details);
});
L'evento change
Infine, se mi interessano solo le modifiche a una schermata specifica, posso ascoltare l'evento
change
di quella schermata.
const firstScreen = (await window.getScreenDetails())[0];
firstScreen.addEventListener('change', async (event) => {
console.log('The first screen has changed.', event, firstScreen);
});
Nuove opzioni a schermo intero
Fino ad ora, potevi richiedere la visualizzazione degli elementi in modalità a schermo intero tramite il metodo
requestFullScreen()
. Il metodo accetta un parametro options
in cui puoi passare
FullscreenOptions
. Finora,
la sua unica proprietà è stata
navigationUI
.
L'API Window Management aggiunge una nuova proprietà screen
che consente di determinare
su quale schermo avviare la visualizzazione a schermo intero. Ad esempio, se vuoi visualizzare la schermata principale
a schermo intero:
try {
const primaryScreen = (await getScreenDetails()).screens.filter((screen) => screen.isPrimary)[0];
await document.body.requestFullscreen({ screen: primaryScreen });
} catch (err) {
console.error(err.name, err.message);
}
Polyfill
Non è possibile eseguire il polyfill dell'API Window Management, ma puoi eseguire lo shim della sua forma in modo da poter programmare esclusivamente in base alla nuova API:
if (!('getScreenDetails' in window)) {
// Returning a one-element array with the current screen,
// noting that there might be more.
window.getScreenDetails = async () => [window.screen];
// Set to `false`, noting that this might be a lie.
window.screen.isExtended = false;
}
Gli altri aspetti dell'API, ovvero i vari eventi di cambio schermo e la proprietà screen
di
FullscreenOptions
, non vengono mai attivati o vengono ignorati silenziosamente dai
browser non supportati.
Demo
Se sei come me, segui da vicino lo sviluppo delle varie criptovalute. (In realtà non lo faccio perché amo questo pianeta, ma, per il bene di questo articolo, supponi che io lo faccia.) Per tenere traccia delle criptovalute che possiedo, ho sviluppato un'app web che mi consente di monitorare i mercati in tutte le situazioni della vita, ad esempio comodamente dal letto, dove ho una configurazione decente a schermo singolo.

Trattandosi di criptovalute, i mercati possono diventare frenetici in qualsiasi momento. Se dovesse succedere, posso spostarmi rapidamente alla mia scrivania, dove ho una configurazione multi-schermo. Posso fare clic sulla finestra di qualsiasi valuta e visualizzare rapidamente tutti i dettagli in una visualizzazione a schermo intero sullo schermo opposto. Di seguito è riportata una mia foto recente scattata durante l'ultimo bagno di sangue di YCY. Mi ha colto completamente di sorpresa e mi ha lasciato con le mani sul viso.

Puoi provare la demo incorporata di seguito o visualizzare il relativo codice sorgente su GitHub.
Sicurezza e autorizzazioni
Il team di Chrome ha progettato e implementato l'API Window Management utilizzando i principi fondamentali definiti in Controlling Access to Powerful Web Platform Features, tra cui controllo utente, trasparenza ed ergonomia. L'API Window Management espone nuove informazioni sugli schermi collegati a un dispositivo, aumentando la superficie di fingerprinting degli utenti, in particolare di quelli con più schermi collegati in modo coerente ai loro dispositivi. Per mitigare questo problema di privacy, le proprietà dello schermo esposte sono limitate al minimo necessario per i casi d'uso comuni di posizionamento. È necessaria l'autorizzazione dell'utente per consentire ai siti di ottenere informazioni multischermo e posizionare le finestre su altri schermi. Mentre Chromium restituisce etichette dettagliate dello schermo, i browser sono liberi di restituire etichette meno descrittive (o anche vuote).
Controllo utente
L'utente ha il pieno controllo dell'esposizione della propria configurazione. Possono accettare o rifiutare la richiesta di autorizzazione e revocare un'autorizzazione concessa in precedenza tramite la funzionalità delle informazioni del sito nel browser.
Controllo aziendale
Gli utenti di Chrome Enterprise possono controllare diversi aspetti dell'API Window Management come descritto nella sezione pertinente delle impostazioni dei gruppi di criteri atomici.
Trasparenza
Il fatto che l'autorizzazione per l'utilizzo dell'API Window Management sia stata concessa è esposto nelle informazioni sul sito del browser ed è anche interrogabile tramite l'API Permissions.
Persistenza delle autorizzazioni
Il browser mantiene le concessioni delle autorizzazioni. L'autorizzazione può essere revocata tramite le informazioni del sito del browser.
Feedback
Il team di Chrome vuole conoscere le tue esperienze con l'API Window Management.
Descrivi la progettazione dell'API
C'è qualcosa nell'API che non funziona come previsto? 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 nel repository GitHub corrispondente o aggiungi i tuoi commenti a un problema esistente.
Segnalare un problema relativo all'implementazione
Hai trovato un bug nell'implementazione di Chrome? L'implementazione è diversa dalla specifica?
- Segnala un bug all'indirizzo new.crbug.com. Assicurati di includere il maggior numero di dettagli possibile, istruzioni semplici per la riproduzione e inserisci
Blink>Screen>MultiScreen
nella casella Componenti.
Mostra il tuo sostegno all'API
Intendi utilizzare l'API Window Management? Il tuo supporto pubblico aiuta il team di Chrome a dare la priorità alle funzionalità e mostra ad altri fornitori di browser quanto sia fondamentale supportarle.
- Condividi il modo in cui prevedi di utilizzarlo nel thread di discussione WICG.
- Invia un tweet a @ChromiumDev utilizzando l'hashtag
#WindowManagement
e facci sapere dove e come lo utilizzi. - Chiedi ad altri fornitori di browser di implementare l'API.
Link utili
- Spec draft
- Spiegazione pubblica
- Demo dell'API Window Management | Demo dell'API Window Management source
- Bug di monitoraggio di Chromium
- Voce di ChromeStatus.com
- Componente Blink:
Blink>Screen>MultiScreen
- TAG Review
- Intenzione di sperimentare
Ringraziamenti
Le specifiche dell'API Window Management sono state modificate da Victor Costan, Joshua Bell e Mike Wasserman. L'API è stata implementata da Mike Wasserman e Adrienne Walker. Questo articolo è stato rivisto da Joe Medley, François Beaufort e Kayce Basques. Grazie a Laura Torrent Puig per le foto.