Ricevere informazioni sugli schermi collegati e posizionare le finestre in base a questi schermi.
API Window Management
L'API Window Management ti consente di enumerare i display collegati alla tua macchina e di posizionare le finestre su schermate specifiche.
Casi d'uso suggeriti
Ecco alcuni esempi di siti che potrebbero utilizzare questa API:
- Gli editor di grafica a più finestre come Gimp possono posizionare vari strumenti di modifica in finestre posizionate con precisione.
- Le sale di negoziazione virtuali possono mostrare le tendenze del mercato in più finestre, ognuna delle quali può essere visualizzata in modalità schermo intero.
- Le app di presentazione possono mostrare le note del relatore sulla schermata principale interna e la presentazione su un proiettore esterno.
Come utilizzare l'API Window Management
Il problema
Purtroppo, l'approccio collaudato per il controllo delle finestre,
Window.open()
, non è consapevole di schermate aggiuntive. Sebbene alcuni aspetti di questa API sembrino un po' antiquati, come il parametro
windowFeatures
DOMString
, ci è stata comunque utile 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 le
dimensioni desiderate come
width
e height
(o innerWidth
e innerHeight
rispettivamente). Ad esempio, per aprire una finestra 400 x 300 a 50 pixel da sinistra e 50 pixel da sopra, puoi utilizzare il seguente 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 è il risultato 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 personale ufficio in casa. La mia è simile a quella nella foto di seguito (se ti interessa, puoi leggere i dettagli completi della mia configurazione). L'iPad accanto al mio MacBook è connesso al laptop tramite Sidecar, quindi, ogni volta che ne ho bisogno, posso trasformare rapidamente l'iPad in un secondo schermo.
Se voglio sfruttare lo schermo più grande, posso mettere il popup del codice di esempio riportato sopra sullo schermo secondario. Lo faccio in questo modo:
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, ma non lo schermo dell'iPad. Il valore width
segnalato per lo 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 farlo. Si tratta dell'API Window Management.
Rilevamento di 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.
L'autorizzazione window-management
può essere interrogata 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 i browser con il vecchio e il nuovo nome dell'autorizzazione, assicurati di utilizzare codice difensivo quando richiedi l'autorizzazione, come nell'esempio seguente.
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.
La proprietà window.screen.isExtended
Per scoprire se più schermi sono connessi al mio dispositivo, 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 è multischermo, posso ottenere maggiori informazioni sul secondo schermo utilizzando Window.getScreenDetails()
. La chiamata di questa funzione mostrerà una richiesta di autorizzazione che mi chiede se il sito può aprire e posizionare finestre sullo schermo. La funzione restituisce una promessa
che si risolve 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 sulle schermate collegate sono disponibili nell'array screens
. Tieni presente che il valore di left
per l'iPad inizia da 1680
, che corrisponde esattamente al valore width
del display integrato. In questo modo, posso determinare esattamente come le schermate sono disposte in modo logico (una accanto all'altra, una sopra l'altra e così via). Ora sono disponibili anche i dati relativi a ogni schermata per indicare se si tratta di una schermata isInternal
o isPrimary
. Tieni presente che lo schermo integrato
non è necessariamente quello principale.
Il campo currentScreen
è un oggetto attivo corrispondente al window.screen
corrente. L'oggetto viene aggiornato in base ai posizionamenti delle finestre cross-screen o alle modifiche del dispositivo.
L'evento screenschange
L'unica cosa che manca ora è un modo per rilevare quando la configurazione dello schermo cambia. Un nuovo evento,
screenschange
, fa esattamente questo: viene attivato ogni volta che la costellazione dello schermo viene modificata. Tieni conto che "screens" è plurale nel nome dell'evento. Ciò significa che l'evento viene attivato ogni volta che una nuova schermata o una schermata esistente viene collegata o scollegata (fisicamente o virtualmente nel caso di Sidecar).
Tieni presente che devi cercare i dettagli della nuova schermata in modo asincrono, poiché l'evento screenschange
non fornisce questi dati. Per cercare i dettagli dello schermo, utilizza l'oggetto in tempo reale da un'interfacciaScreens
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 in tempo reale
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
della schermata.
const firstScreen = (await window.getScreenDetails())[0];
firstScreen.addEventListener('change', async (event) => {
console.log('The first screen has changed.', event, firstScreen);
});
Nuove opzioni per lo schermo intero
Fino a ora, potevi richiedere la visualizzazione degli elementi in modalità a schermo intero tramite il metodo appropriatamente denominato
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 schermata avviare la visualizzazione a schermo intero. Ad esempio, se vuoi visualizzare la schermata principale in modalità 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 scrivere codice esclusivamente per la 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 modifica della schermata e la proprietà screen
di
FullscreenOptions
, non verrebbero mai attivati o ignorati silenziosamente, rispettivamente, dai browser che non supportano la funzionalità.
Demo
Se sei come me, tieni d'occhio lo sviluppo delle varie criptovalute. In realtà non lo farei mai perché amo questo pianeta, ma, per il bene di questo articolo, supponi che lo abbia fatto. 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 mio letto, dove ho una configurazione decente con un solo schermo.
Poiché si tratta di criptovalute, i mercati possono diventare frenetici in qualsiasi momento. In questo caso, posso spostarmi rapidamente alla mia scrivania, dove ho una configurazione multischermo. Posso fare clic sulla finestra di qualsiasi valuta e visualizzare rapidamente i dettagli completi in una visualizzazione a schermo intero sullo schermo opposto. Di seguito è riportata una mia foto recente scattata durante l'ultimo massacro di YCY. Mi ha colto completamente alla sprovvista e mi ha lasciato con le mani sul viso.
Puoi provare la demo incorporata di seguito o visualizzarne il codice sorgente su glitch.
Sicurezza e autorizzazioni
Il team di Chrome ha progettato e implementato l'API Window Management utilizzando i principi di base definiti in Controllo dell'accesso a potenti funzionalità della piattaforma web, tra cui il controllo utente, la trasparenza e l'ergonomia. L'API Window Management espone nuove informazioni sulle schermate connesse a un dispositivo, aumentando la superficie di fingerprinting degli utenti, in particolare quelli con più schermate connesse costantemente ai loro dispositivi. Come misura di mitigazione di questo problema di privacy, le proprietà delle schermate esposte sono limitate al minimo necessario per i casi d'uso comuni dei posizionamenti. È necessaria l'autorizzazione dell'utente per consentire ai siti di ricevere informazioni su più schermi e posizionare finestre su altre schermate. Sebbene Chromium restituisca etichette dettagliate delle schermate, i browser sono liberi di restituire etichette meno descrittive (o addirittura vuote).
Controllo utente
L'utente ha il controllo completo dell'esposizione della sua configurazione. Possono accettare o rifiutare la richiesta di autorizzazione e revocare un'autorizzazione concessa in precedenza tramite la funzionalità Informazioni sul sito nel browser.
Controllo aziendale
Gli utenti di Chrome Enterprise possono controllare diversi aspetti dell'API Window Management come indicato nella sezione pertinente delle impostazioni dei gruppi di criteri atomici.
Trasparenza
L'eventuale autorizzazione all'utilizzo dell'API Window Management è esposta nelle informazioni sul sito del browser ed è anche disponibile per query tramite l'API Permissions.
Persistenza delle autorizzazioni
Il browser mantiene le autorizzazioni concesse. L'autorizzazione può essere revocata tramite le informazioni sul sito del browser.
Feedback
Il team di Chrome vuole conoscere la tua esperienza con l'API Window Management.
Fornisci informazioni sul design dell'API
C'è qualcosa nell'API che non funziona come previsto? Oppure mancano metodi o proprietà di cui hai bisogno per implementare la tua idea? Hai domande o commenti sul modello di sicurezza?
- Invia una segnalazione relativa alle specifiche nel repository GitHub corrispondente o aggiungi le tue considerazioni a un problema esistente.
Segnalare un problema con l'implementazione
Hai trovato un bug nell'implementazione di Chrome? Oppure l'implementazione è diversa dalla specifica?
- Invia 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. Glitch è ideale per condividere riproduzioni rapide e semplici.
Mostra il supporto per l'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.
- Spiega come prevedi di utilizzarlo nel thread di Discourse del WICG.
- Invia un tweet all'account @ChromiumDev utilizzando l'hashtag
#WindowManagement
e facci sapere dove e come lo stai utilizzando. - Chiedi ad altri fornitori di browser di implementare l'API.
Link utili
- Bozza delle specifiche
- Spiegazione pubblica
- Demo dell'API Window Management | Source della demo dell'API Window Management
- Bug di monitoraggio di Chromium
- Voce di ChromeStatus.com
- Componente lampeggiante:
Blink>Screen>MultiScreen
- Revisione del TAG
- Intento di partecipare all'esperimento
Ringraziamenti
Le specifiche dell'API Window Management sono state redatte da Victor Costan, Joshua Bell e Mike Wasserman. L'API è stata implementata da Mike Wasserman e Adrienne Walker. Questo articolo è stato esaminato da Joe Medley, François Beaufort, e Kayce Basques. Grazie a Laura Torrent Puig per le foto.