Obtén información sobre las pantallas conectadas y la posición de las ventanas en relación con esas pantallas.
API de Window Management
La API de Window Management te permite enumerar las pantallas conectadas a tu máquina y colocar ventanas en pantallas específicas.
Casos de uso sugeridos
Estos son algunos ejemplos de sitios que pueden usar esta API:
- Editores gráficos multiventana Gimp puede colocar varias de edición de texto en ventanas precisas.
- Las mesas de operaciones virtuales pueden mostrar las tendencias del mercado en múltiples ventanas, cualquiera de las cuales puede verse en modo de pantalla completa.
- Las aplicaciones de presentación de diapositivas pueden mostrar notas del orador en la pantalla principal interna y la presentación en un proyector externo.
Cómo usar la API de Window Management
El problema
El enfoque
antiguo para el control de ventanas
Window.open()
, desafortunadamente
no sea consciente de las pantallas adicionales. Si bien algunos aspectos de esta API parecen un poco arcaicos, como su
windowFeatures
DOMString
, nos ha funcionado bien a lo largo de los años. Para especificar la configuración
position, puedes pasar el
coordenadas como left
y top
(o screenX
y screenY
respectivamente) y pasa la cantidad deseada
tamaño como
width
y height
(o innerWidth
y innerHeight
, respectivamente). Por ejemplo, para abrir una
una ventana de 400 × 300 a 50 píxeles desde la izquierda y 50 píxeles desde la parte superior. Este es el código que
podría usar:
const popup = window.open(
'https://example.com/',
'My Popup',
'left=50,top=50,width=400,height=300',
);
Puedes obtener información sobre la pantalla actual en la
window.screen
, que
muestra un objeto Screen
. Este es el
de salida en mi MacBook Pro de 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
*/
Al igual que la mayoría de las personas que trabajan en el área de tecnología, tuve que adaptarme a la nueva realidad laboral y preparar mi oficina en casa. El mío se ve en la siguiente foto (si te interesa, puedes leer la todos los detalles de mi configuración). El iPad junto a mi MacBook está conectado a la laptop mediante Sidecar, para que siempre que lo necesite, puedo en una segunda pantalla.
![Banco escolar sobre dos sillas. Encima de los bancos de la escuela hay cajas de zapatos que sostienen una laptop y dos iPads a su alrededor.](https://developer.chrome.com/static/docs/capabilities/web-apis/window-management/image/school-bench-two-chairs-8465336393f71.jpg?authuser=19&hl=es)
Si quiero aprovechar la pantalla más grande, puedo colocar la ventana emergente muestra de código anterior en la segunda pantalla. Listo así:
popup.moveTo(2500, 50);
Esta es una suposición aproximada, ya que no hay forma de conocer las dimensiones de la segunda pantalla. La información
de window.screen
solo cubre la pantalla integrada, pero no la del iPad. El width
informado
de la pantalla integrada era de 1680
píxeles, por lo que mover a 2500
píxeles podría cambiar la
al iPad, ya que s sé que está ubicada a la derecha de mi MacBook. Cómo
¿puedo hacer esto en general? Resulta que hay una mejor manera que adivinar. De esa manera, se crea
API de Window Management
Detección de funciones
Para verificar si se admite la API de Window Management, usa lo siguiente:
if ('getScreenDetails' in window) {
// The Window Management API is supported.
}
El permiso window-management
Antes de poder usar la API de Window Management, debo solicitar permiso al usuario para hacerlo.
El permiso window-management
se puede consultar con el
API de Permissions de la siguiente manera:
let granted = false;
try {
const { state } = await navigator.permissions.query({ name: 'window-management' });
granted = state === 'granted';
} catch {
// Nothing.
}
Mientras se usan los navegadores con el nombre de permiso anterior y el nuevo, asegúrate de usar código defensivo al solicitar permiso, como se muestra en el siguiente ejemplo.
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;
});
El navegador puede elige mostrar la solicitud de permiso dinámicamente en el primer intento de usar cualquiera de los métodos de la nueva API. Sigue leyendo para obtener más información.
La propiedad window.screen.isExtended
Para saber si hay más de una pantalla conectada a mi dispositivo, accedo al
window.screen.isExtended
. Muestra true
o false
. En mi configuración, muestra true
.
window.screen.isExtended;
// Returns `true` or `false`.
El método getScreenDetails()
Ahora que sé que la configuración actual es multipantalla, puedo obtener más información sobre las
segunda pantalla con Window.getScreenDetails()
. Si llamas a esta función, se mostrará un mensaje de permiso que
me pregunta si el sitio puede abrirse y colocar ventanas en mi pantalla. La función muestra una promesa
que se resuelve con un objeto ScreenDetailed
. En mi MacBook Pro 13 con un iPad conectado,
Esto incluye un campo screens
con dos objetos 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
}]
}
*/
La información sobre las pantallas conectadas está disponible en el array screens
. Ten en cuenta cómo el valor de
El valor de left
para iPad comienza en 1680
, que es exactamente el width
de la pantalla integrada. Esta
me permite determinar exactamente cómo las pantallas están organizadas lógicamente (una al lado de la otra, por encima de
entre sí, etcétera). Ahora también hay datos para cada pantalla que muestran si es de tipo isInternal
y si es isPrimary
. Ten en cuenta que la pantalla integrada
no es necesariamente la pantalla principal.
El campo currentScreen
es un objeto activo que corresponde al window.screen
actual. El objeto
se actualiza en posiciones de ventanas en varias pantallas o cambios en los dispositivos.
El evento screenschange
Lo único que falta ahora es una forma de detectar cuándo cambia la configuración de la pantalla. Un evento nuevo,
screenschange
hace exactamente eso: se activa cada vez que se modifica la constelación de pantalla. (Aviso
que las "pantallas" está en plural en el nombre del evento). Esto significa que el evento se activa cada vez que una pantalla nueva o
la pantalla existente está (física o virtualmente, en el caso del Sidecar) enchufada o desconectada.
Ten en cuenta que debes buscar los detalles de la nueva pantalla de forma asíncrona, ya que el evento screenschange
no proporciona estos datos. Para buscar los detalles de la pantalla, usa el objeto activo de un contenedor
Screens
.
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;
}
});
El evento currentscreenchange
Si solo me interesan los cambios en la pantalla actual (es decir, el valor del objeto activo
currentScreen
), puedo escuchar el 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);
});
El evento change
Por último, si solo me interesan los cambios
en una pantalla concreta, puedo escuchar
change
evento.
const firstScreen = (await window.getScreenDetails())[0];
firstScreen.addEventListener('change', async (event) => {
console.log('The first screen has changed.', event, firstScreen);
});
Nuevas opciones de pantalla completa
Hasta ahora, podías solicitar que los elementos se mostraran en modo de pantalla completa a través del llamado
requestFullScreen()
. El método toma un parámetro options
, en el que puedes pasar
FullscreenOptions
Hasta ahora,
su única propiedad ha sido
navigationUI
La API de Window Management agrega una nueva propiedad screen
que te permite determinar
en qué pantalla se inicia la vista de pantalla completa. Por ejemplo, si quieres que la pantalla principal
pantalla completa:
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
No es posible crear polyfills de la API de Window Management, pero puedes corregir su forma para que puedes programar exclusivamente con la nueva 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;
}
Los demás aspectos de la API, es decir, los distintos eventos de cambio de pantalla y la propiedad screen
de
FullscreenOptions
, nunca se activaría ni se ignorará en silencio, respectivamente,
navegadores no compatibles.
Demostración
Si eres de alguna forma como yo, debes prestar atención al desarrollo de las diversas criptomonedas. (En realidad, no lo hago porque amo este planeta, pero en este artículo, supón que did.) Para hacer un seguimiento de las criptomonedas que tengo, desarrollé una aplicación web que me permite ver los mercados en todas las situaciones de la vida, por ejemplo, desde la comodidad de mi cama, donde tengo un configuración de una sola pantalla.
![Pantalla de TV enorme al final de una cama con las piernas del autor parcialmente visibles. En la pantalla, se ve una mesa de comercio de criptomonedas falsas.](https://developer.chrome.com/static/docs/capabilities/web-apis/window-management/image/massive-tv-screen-the-en-c57bfb0e325ff.jpg?authuser=19&hl=es)
En cuanto a las criptomonedas, los mercados pueden volverse agitados en cualquier momento. Si esto sucede, puedo rápidamente y pasaré a mi escritorio donde tengo una configuración multipantalla. puedo hacer clic en la ventana de cualquier moneda y ver rápidamente todos los detalles en una vista de pantalla completa en la pantalla opuesta. A continuación, hay una foto reciente de que me tomé en el último baño de sangre de YCY. Me atrapó completamente por sorpresa y me dejó con las manos en la cara.
![El autor, con las manos en la cara de pánico, mira la mesa de comercio de criptomonedas falsas.](https://developer.chrome.com/static/docs/capabilities/web-apis/window-management/image/the-author-his-hands-hi-0d430520b074a.jpg?authuser=19&hl=es)
Puedes jugar con la demostración incorporada a continuación o ver su código fuente en caso de error.
Seguridad y permisos
El equipo de Chrome diseñó e implementó la API de Window Management con la base de que se definen en Controla el acceso a las funciones potentes de la plataforma web, incluidos el control de usuario, la transparencia y la ergonomía. La API de Window Management expone nueva información sobre las pantallas conectadas a un dispositivo, lo que aumenta la superficie de huella digital de en especial, aquellos con varias pantallas conectadas a sus dispositivos de manera constante. Como uno para mitigar esta preocupación por la privacidad, las propiedades de la pantalla expuesta se limitan a lo mínimo necesario para casos de uso de posiciones comunes. Se requiere permiso del usuario para que los sitios tengan la función multipantalla información y colocar las ventanas en otras pantallas. Si bien Chromium devuelve etiquetas de pantalla detalladas, los navegadores tienen la libertad de mostrar etiquetas menos descriptivas (o incluso vacías).
Control de usuarios
El usuario tiene el control total de la exposición de su configuración. Puede aceptar o rechazar el solicitud de permiso y revocar un permiso otorgado previamente a través de la función de información del sitio en el navegador.
Control empresarial
Los usuarios de Chrome Enterprise pueden controlar varios aspectos de la API de Window Management, como descritos en la sección relevante de Grupos atómicos de políticas configuración.
Transparencia
El hecho de que se haya otorgado permiso para usar la API de Window Management que se expone en la información del sitio del navegador y que también se puede consultar a través de la API de Permissions.
Persistencia de permisos
El navegador conserva los otorgamientos de permisos. Se puede revocar el permiso a través del sitio del navegador. información.
Comentarios
El equipo de Chrome quiere conocer tu experiencia con la API de Window Management.
Cuéntanos sobre el diseño de la API
¿Algo en la API no funciona como esperabas? ¿O faltan métodos o propiedades que necesitas para implementar tu idea? Haz una pregunta o comentario sobre la seguridad modelo?
- Informa un problema de especificaciones en el repositorio de GitHub correspondiente o agrega lo que piensas a un archivo problema.
Informar un problema con la implementación
¿Encontraste un error en la implementación de Chrome? ¿O la implementación es diferente de la especificación?
- Informa un error en new.crbug.com. Asegúrate de incluir todos los detalles que
, obtén instrucciones sencillas para reproducir y, luego, ingresa
Blink>Screen>MultiScreen
en el Componentes. Glitch funciona muy bien para compartir repros rápidos y fáciles.
Demuestra compatibilidad con la API
¿Planeas usar la API de Window Management? Tu apoyo público ayuda a Chrome para priorizar funciones y muestra a otros proveedores de navegadores la importancia de brindar compatibilidad con ellas.
- Comparte cómo piensas usarlo en la conversación del discurso de WICG.
- Envía un tweet a @ChromiumDev con el hashtag
#WindowManagement
y cuéntanos dónde y cómo la usas. - Solicita a otros proveedores de navegadores que implementen la API.
Vínculos útiles
- Borrador de especificaciones
- Explicación pública
- Demostración de la API de Window Management | Demostración de la API de Window Management fuente
- Error de seguimiento de Chromium
- Entrada de ChromeStatus.com
- Componente de parpadeo:
Blink>Screen>MultiScreen
- Revisión del TAG
- Intención de experimentar
Agradecimientos
El usuario editó la especificación de la API de Window Management Victor Costan, Joshua Bell y Mike Wasserman. La API fue implementada por Mike Wasserman y Adrienne Walker. Este artículo fue revisado por Joe Medley, François Beaufort, y Kayce Basques. Gracias a Laura Torrent Puig por las fotos.