Mesa de trading simulada que muestra múltiples criptodivisas falsas y sus gráficos de precios.

Administrar varias pantallas con la API de colocación de ventanas multipantalla

Obtenga información sobre las pantallas conectadas y la posición de las ventanas en relación con esas pantallas.

Published on Updated on

Translated to: English, 한국어, 中文

La API de colocación de ventanas multipantalla es parte del proyecto de capacidades y está actualmente en desarrollo. Esta publicación se actualizará a medida que avance la implementación.

La API de colocación de ventanas multipantalla le permite enumerar las pantallas conectadas a su máquina y colocar ventanas en pantallas específicas.

Casos de uso sugeridos

Ejemplos de sitios que pueden usar esta API incluyen:

  • Los editores gráficos de ventanas múltiples tipo Gimp pueden colocar varias herramientas de edición en ventanas colocadas con precisión.
  • Las mesas de trading virtual pueden mostrar las tendencias del mercado en múltiples ventanas, cualquiera de las cuales se puede ver 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.

Estado actual

PasoEstado
1. Crea un explicadorCompletado
2. Crear borrador inicial de especificaciónCompletado
3. Recopile comentarios y repita el diseñoEn curso
4. Prueba de origen

En curso

5. LanzamientoNo empezado

Cómo utilizar la API de colocación de ventanas multipantalla

El problema

El enfoque probado con el tiempo para controlar las ventanas, Window.open(), desafortunadamente no toma en cuenta las pantallas adicionales. Si bien algunos aspectos de esta API parecen un poco arcaicos, como su parámetro windowFeatures DOMString, nos ha servido bien a lo largo de los años. Para especificar la posición de una ventana, puede pasar las coordenadas como left y top (o screenX y screenY respectivamente) y pasar el tamaño deseado como width y height (o innerwidth e innerHeight respectivamente). Por ejemplo, para abrir una ventana de 400 × 300 a 50 píxeles de la izquierda y 50 píxeles de la parte superior, podría usar este código:

const popup = window.open(
'https://example.com/',
'My Popup',
'left=50,top=50,width=400,height=300',
);

Puede obtener información sobre la pantalla actual mirando la window.screen, que devuelve un objeto Screen. Esta es la salida en mi 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
*/

Como la mayoría de las personas que trabajan en campos de tecnología, he tenido que adaptarme a la nueva realidad laboral y montar mi propia oficina en casa. La mía se ve como en la foto de abajo (si está interesado, puede leer los detalles completos sobre mi configuración). El iPad al lado de mi MacBook está conectado a la computadora portátil a través de Sidecar , por lo que siempre que lo necesito, puedo convertir rápidamente el iPad en una segunda pantalla.

Banco escolar en dos sillas. En la parte superior del banco escolar hay cajas de zapatos que sostienen una computadora portátil y dos iPads a su alrededor.
Una configuración multipantalla.

Si quiero aprovechar la pantalla más grande, puedo colocar la ventana emergente del ejemplo de código anterior en la segunda pantalla. Lo hago 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 incorporada, pero no la pantalla del iPad. El width informado de la pantalla incorporada fue de 1680 píxeles, por lo que pasar a 2500 píxeles podría funcionar para cambiar la ventana al iPad, ya que que está ubicada a la derecha de mi MacBook. ¿Cómo puedo hacer esto en un caso general? Resulta que hay una forma mejor que tratar de adivinar. Esa forma es la API de colocación de ventanas multipantalla.

Detección de características

Para comprobar si la API de colocación de ventanas multipantalla es compatible, utilice:

if ('getScreenDetails' in window) {
// The Multi-Screen Window Placement API is supported.
}

El permiso window-placement

Antes de poder utilizar la API de colocación de ventanas multipantalla, debo pedirle permiso al usuario para hacerlo. El nuevo window-placement se puede consultar con la API de permisos de la siguiente manera:

let granted = false;
try {
const { state } = await navigator.permissions.query({ name: 'window-placement' });
granted = state === 'granted';
} catch {
// Nothing.
}

El navegador puede optar por mostrar la solicitud de permiso de forma dinámica en el primer intento de utilizar cualquiera de los métodos de la nueva API. Siga 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, yo accedo a la propiedad window.screen.isExtended. Devuelve true o false. Para mi configuración, devuelve 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 la segunda pantalla usando Window.getScreenDetails(). Llamar a esta función mostrará un mensaje de permiso que me pregunta si el sitio puede abrir y colocar ventanas en mi pantalla. La función devuelve una promesa que se resuelve con un objeto ScreenDetailed. En mi MacBook Pro 13 con un iPad conectado, esto incluye un campo de 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: ""
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: ""
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 la matriz de screens. Observe cómo el valor de left para el iPad comienza en 1680, que es exactamente el width de la pantalla incorporada. Esto me permite determinar exactamente cómo están dispuestas lógicamente las pantallas (una al lado de la otra, una encima de la otra, etc.). También hay datos ahora de cada pantalla para mostrar si es interna (isInternal) y si es una Principal isPrimary. Tenga en cuenta que la pantalla incorporada no es necesariamente la pantalla principal .

El campo currentScreen es un objeto vivo correspondiente a la pantalla window.screen actual. El objeto se actualiza en ubicaciones cruzadas de ventanas o cambios de dispositivo.

El evento screenschange

Lo único que falta ahora es una forma de detectar cuándo cambia la configuración de mi pantalla. Un nuevo evento, screenschange, hace exactamente eso: se activa cada vez que se modifica la constelación de pantallas. (Observe que "screens" es plural en el nombre del evento). Esto significa que el evento se activa cada vez que se conecta o desconecta una nueva pantalla o una pantalla existente (física o virtualmente en el caso de Sidecar).

Tenga en cuenta que debe buscar los detalles de la nueva pantalla de forma asincrónica, el evento screenschange por sí no proporciona estos datos. Para buscar los detalles de la pantalla, use el objeto vivo desde una interfaz de Screens en caché.

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 sólo estoy interesado en los cambios en la pantalla actual (es decir, el valor del objeto directo 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

Finalmente, si solo estoy interesado en cambios en una pantalla concreta, puedo escuchar el evento change.

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ía solicitar que los elementos se mostraran en modo de pantalla completa a través del método requestFullScreen(). El método toma un parámetro options donde puede pasar FullscreenOptions. Hasta ahora, su única propiedad ha sido navigationUI. La API de colocación de ventanas multipantalla agrega una nueva propiedad screen que le permite determinar en qué pantalla iniciar la vista de pantalla completa. Por ejemplo, si desea que la pantalla principal esté en 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 aplicar polyfill a la API de colocación de ventanas multipantalla, pero puede ajustar su forma para poder codificar exclusivamente hacia 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 otros aspectos de la API, es decir, los diversos eventos de cambio de pantalla y la propiedad screen del FullscreenOptions, simplemente nunca se activarían o serían ignorados en silencio, respectivamente, por los navegadores no compatibles.

Demostración

Si usted es como yo, vigila de cerca el desarrollo de las distintas criptomonedas. (En realidad, no lo hago mucho porque amo este planeta, pero, por el bien de este artículo, asuma que lo hago). Para realizar un seguimiento de las criptomonedas que poseo, he desarrollado una aplicación web que me permite ver los mercados en todas las situaciones de la vida, como desde la comodidad de mi cama, donde tengo una configuración decente de pantalla única.

Pantalla de televisión enorme al final de una cama con las piernas del autor parcialmente visibles. En la pantalla, una mesa de trading de criptodivisas falsas.
Relajándose y observando los mercados.

Al tratarse de criptomonedas, los mercados pueden agitarse en cualquier momento. Si esto sucediera, puedo moverme rápidamente a mi escritorio donde tengo una configuración de múltiples pantallas. Puedo hacer clic en la ventana de cualquier moneda y ver rápidamente los detalles completos en una vista de pantalla completa en la pantalla opuesta. A continuación se muestra una foto reciente mía tomada durante el último baño de sangre de YCY. Me tomó completamente desprevenido y me dejó con las manos en la cara.

El autor con las manos en la cara de pánico mirando la mesa de trading de criptomonedas falsas.
En pánico, presenciando el baño de sangre de YCY.

Puede jugar con la demostración incrustada a continuación, o ver su código fuente en glitch.

Seguridad y permisos

El equipo de Chrome ha diseñado e implementado la API de colocación de ventanas multipantalla utilizando los principios básicos definidos en Control del acceso a las potentes funciones de la plataforma web, incluyendo el control del usuario, la transparencia y la ergonomía. La API de colocación de ventanas multipantalla expone nueva información sobre las pantallas conectadas a un dispositivo, lo que aumenta la superficie de huellas dactilares de los usuarios, especialmente aquellos con varias pantallas conectadas constantemente a sus dispositivos. Como mitigación de este problema de privacidad, las propiedades de la pantalla expuesta se limitan al mínimo necesario para los casos de uso común de la ubicación. Se requiere permisos de usuario para que los sitios obtengan información multipantalla y coloquen ventanas en otras pantallas.

Control de usuario

El usuario tiene el control total de la exposición de su configuración. Pueden aceptar o rechazar la solicitud de permiso y revocar un permiso otorgado previamente a través de la función de información del sitio en el navegador.

Transparencia

El hecho de que se haya otorgado el permiso para usar la API de colocación de ventanas multipantalla se muestra en la información del sitio del navegador y también se puede consultar a través de la API de permisos.

Persistencia del permiso

El navegador conserva las concesiones de permisos. El permiso se puede revocar a través de la información del sitio del navegador.

Retroalimentación

El equipo de Chrome desea conocer sus experiencias con la API de colocación de ventanas multipantalla.

Cuéntenos sobre el diseño de la API

¿Hay algo en la API que no funciona como esperaba? ¿O faltan métodos o propiedades que necesita para implementar su idea? ¿Tiene alguna pregunta o comentario sobre el modelo de seguridad?

  • Reporte un problema de especificaciones en el repositorio de GitHub correspondiente o agregue sus comentarios a un reporte existente.

Reporte problemas con la implementación

¿Encontró un error con la implementación en Chrome? ¿O la implementación es diferente de la especificación?

  • Reporte los errores en new.crbug.com. Asegúrese de incluir todos los detalles que pueda, instrucciones simples para reproducir el error e ingrese Blink>WindowDialog en el cuadro Components. Glitch funciona muy bien para compartir repros rápidos y fáciles.

Muestre su apoyo a la API

¿Está pensando en utilizar la API de colocación de ventanas multipantalla? Su apoyo público ayuda al equipo de Chrome a priorizar las funciones y muestra a otros proveedores de navegadores lo importante que es brindarles soporte.

  • Comparta cómo planea usarlo en el hilo WICG Discourse .
  • Envíe un tweet a @ChromiumDev utilizando el hashtag #WindowPlacement y díganos dónde y cómo lo está utilizando.
  • Solicite a otros proveedores de navegadores que implementen la API.

Enlaces útiles

Agradecimientos

Victor Costan y Joshua Bell editaron la especificación de la API de colocación de ventanas multipantalla. 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.

Updated on Improve article

We serve cookies on this site to analyze traffic, remember your preferences, and optimize your experience.