Administración de ventanas

Una PWA fuera del navegador administra su propia ventana. Obtén información sobre las APIs y las capacidades para administrar una ventana dentro del sistema operativo.

Ejecutar en tu propia ventana, administrada por tu PWA, tiene todas las ventajas y responsabilidades de cualquier ventana en ese sistema operativo, como las siguientes:

  • La capacidad de mover y cambiar el tamaño de la ventana en sistemas operativos multiventana, como Windows o ChromeOS
  • Compartir la pantalla con otras ventanas de apps, como en el modo de división de iPadOS o el modo de pantalla dividida de Android
  • Aparecen en docks, barras de tareas y en el menú Alt+Tab en computadoras, y en listas de ventanas de multitarea en dispositivos móviles.
  • La capacidad de minimizar, mover la ventana entre pantallas y escritorios, y cerrarla en cualquier momento

Cómo mover y cambiar el tamaño de la ventana

La ventana de tu PWA puede tener cualquier tamaño y ubicarse en cualquier lugar de la pantalla en los sistemas operativos para computadoras. De forma predeterminada, cuando el usuario abre la PWA por primera vez después de la instalación, esta obtiene un tamaño de ventana predeterminado que equivale a un porcentaje de la pantalla actual, con una resolución máxima de 1,920 x 1,080 ubicada en la esquina superior izquierda de la pantalla.

El usuario puede mover y cambiar el tamaño de la ventana, y el navegador recordará la última preferencia. La próxima vez que el usuario abra la app, la ventana conservará el tamaño y la posición del uso anterior.

No hay forma de definir el tamaño y la posición preferidos de tu PWA en el manifiesto. Solo puedes cambiar la posición y el tamaño de la ventana con la API de JavaScript. Desde tu código, puedes mover y cambiar el tamaño de tu propia ventana de PWA con las funciones moveTo(x, y) y resizeTo(x, y) del objeto window.

Por ejemplo, puedes cambiar el tamaño y mover la ventana de tu APW cuando se cargue con el siguiente código:

document.addEventListener("DOMContentLoaded", event => {
   // we can move only if we are not in a browser's tab
   isBrowser = matchMedia("(display-mode: browser)").matches;
   if (!isBrowser) {
      window.moveTo(16, 16);
      window.resizeTo(800, 600);
   }
});

Puedes consultar el tamaño y la posición actuales de la pantalla con el objeto window.screen, y puedes detectar cuándo se cambia el tamaño de la ventana con el evento resize del objeto window. No hay ningún evento para capturar el movimiento de la ventana, por lo que tu opción es consultar la posición con frecuencia.

En lugar de mover y cambiar el tamaño de la ventana de forma absoluta, puedes moverla y cambiar su tamaño de forma relativa con moveBy() y resizeBy().

Explorar otros sitios

Si quieres enviar al usuario a un sitio externo que está fuera del alcance de tu PWA, puedes hacerlo con un elemento <a href> HTML estándar. Usa location.href o abre una ventana nueva en plataformas compatibles.

Cuando visitas una URL que está fuera del alcance de tu manifiesto, el motor del navegador de tu APW renderiza un navegador integrado en el contexto de tu ventana.

Un navegador integrado en la app de una PWA para computadoras cuando se navega por una URL que está fuera del alcance.

Estas son algunas funciones de los navegadores integrados en la app:

  • Aparecen sobre tu contenido.
  • Tienen una barra de direcciones estática que muestra el origen actual, el título de la ventana y un menú. Por lo general, tienen el mismo tema que el theme_color de tu manifiesto.
  • En el menú contextual, puedes abrir esa URL en el navegador.
  • Los usuarios pueden cerrar el navegador o volver.

Mientras el navegador integrado en la app está en la pantalla, tu APW espera en segundo plano, como si otra ventana la estuviera ocultando.

Un navegador en la app en un iPhone cuando se navega por una URL que está fuera del alcance dentro de una AWP independiente.
Un navegador integrado en la app en Android cuando se navega por una URL que está fuera del alcance dentro de una AWP independiente.

Flujos de autorización

Muchos flujos de autenticación y autorización web requieren que se redireccione al usuario a una URL diferente en un origen diferente para adquirir un token que regrese al origen de tu PWA, como con OAuth 2.0.

En estos casos, el navegador integrado en la app sigue este proceso:

  1. El usuario abre tu PWA y hace clic en Acceder.
  2. Tu PWA redirecciona al usuario a una URL que está fuera del alcance de la PWA, por lo que el motor de renderización abre un navegador integrado en la app dentro de tu PWA.
  3. El usuario puede cancelar el navegador integrado en la app y volver a tu PWA en cualquier momento.
  4. El usuario accede al navegador integrado en la app. El servidor de autenticación redirecciona al usuario al origen de tu PWA y envía el token como argumento.
  5. El navegador integrado en la app se cierra automáticamente cuando detecta una URL que forma parte del alcance de la PWA.
  6. El motor redirecciona la navegación de la ventana principal de la PWA a la URL a la que se dirigió el servidor de autenticación mientras estaba en el navegador integrado en la app.
  7. Tu AWP obtiene el token, lo almacena y renderiza la AWP.

Forzar la navegación de un navegador

Si deseas forzar la apertura del navegador con una URL y no con un navegador integrado en la app, puedes usar el destino _blank de los elementos <a href>. Esto solo funciona en las PWA para computadoras. En dispositivos móviles, no hay opción para abrir un navegador con una URL.

function openBrowser(url) {
    window.open("url", "_blank", "");
}

Abrir ventanas nuevas

En computadoras, los usuarios pueden abrir más de una ventana de la misma PWA. Cada ventana tiene una navegación diferente para el mismo start_url, como si abrieras dos pestañas del navegador de la misma URL. En el menú de la PWA, los usuarios pueden seleccionar Archivo y, luego, Nueva ventana. Desde el código de tu AWP, puedes abrir una ventana nueva con la función open().

function openNewWindow() {
    window.open("/", "new-window", "width=600,height=600");
}

La misma AWP instalada con varias ventanas abiertas en un sistema operativo de escritorio.

Cuando llamas a open() dentro de una ventana de PWA en iOS o iPadOS, se devuelve null y no se abre una ventana. Abrir ventanas nuevas en Android crea un navegador integrado en la app nuevo para la URL, incluso si esta se encuentra dentro del alcance de tu PWA, que, por lo general, no activa una experiencia de navegación externa.

Título de la ventana

El elemento <title> se usaba principalmente para fines de SEO, ya que el espacio dentro de una pestaña del navegador es limitado. Cuando pasas del navegador a tu ventana en una AWP, tienes disponible todo el espacio de la barra de título.

Puedes definir el contenido de la barra de título:

  • De forma estática en tu elemento <title> de HTML
  • Cambiar de forma dinámica la propiedad de cadena document.title en cualquier momento

En las PWA para computadoras, el título es fundamental y se usa en la barra de título de la ventana y, a veces, en el administrador de tareas o en la selección de multitareas. Si tienes una aplicación de una sola página, es posible que desees actualizar el título en cada ruta.

Modo con pestañas

El modo con pestañas es una función experimental que permite que tu AWP tenga un diseño basado en pestañas, similar a un navegador web. En este caso, el usuario puede abrir varias pestañas en la misma PWA, pero todas vinculadas en la misma ventana del sistema operativo.

Puedes leer más sobre esta función experimental en Modo de aplicación con pestañas para PWA.

Superposición de controles de ventana

Ya mencionamos que puedes cambiar el título de la ventana definiendo el valor del elemento <title> o la propiedad document.title. Pero siempre es un valor de cadena. ¿Qué pasaría si pudiéramos diseñar la barra de título con HTML, CSS e imágenes? La superposición de controles de ventana, una función experimental en Microsoft Edge y Google Chrome para las PWA de escritorio, puede ser útil.

Puedes leer más sobre esta capacidad en Personaliza la superposición de controles de ventana de la barra de título de la AWP.

Con la superposición de controles de ventana, puedes renderizar contenido en la barra de título.

Administración de ventanas

Con varias pantallas, los usuarios quieren usar todo el espacio disponible. Por ejemplo:

  • Los editores de gráficos con varias ventanas, como Gimp, pueden colocar varias herramientas de edición en ventanas posicionadas con precisión.
  • Las mesas de negociación virtuales pueden mostrar las tendencias del mercado en varias ventanas, cualquiera de las cuales se puede ver en modo de pantalla completa.
  • Las apps de presentación de diapositivas pueden mostrar las notas del orador en la pantalla principal interna y la presentación en un proyector externo.

La API de Window Management permite que las APW hagan exactamente eso y mucho más.

Cómo obtener detalles de la pantalla

La API de Window Management agrega un nuevo método, window.getScreenDetails(), que devuelve un objeto con pantallas como un array inmutable de pantallas adjuntas. También hay un objeto activo al que se puede acceder desde ScreenDetails.currentScreen, que corresponde al window.screen actual.

El objeto que se devuelve también activa un evento screenschange cuando cambia el array screens. (Esto no sucede cuando se cambian los atributos en pantallas individuales). Las pantallas individuales, ya sean window.screen o una pantalla en el array screens, también activan un evento change cuando cambian sus atributos.

// Request an object with a screen objects
const screenDetails = await window.getScreenDetails();
screenDetails.screens[0].isPrimary;  // e.g. true
screenDetails.screens[0].isInternal;  // e.g. true
screenDetails.screens[0].label;  // e.g. 'Samsung Electric Company 28"'

// Access the live object corresponding to the current `window.screen`.
// The object is updated on cross-screen window placements or device changes.
screenDetails.currentScreen;
screenDetails.addEventListener('screenschange', function() {
 // NOTE: Does not fire on changes to attributes of individual screens.
  const screenCount = screenDetails.screens.length;
  const currentScreen screenDetails.currentScreen.id;
});

Si el usuario o el sistema operativo mueven la ventana de tu APW de una pantalla a otra, también se activa un evento currentscreenchange desde el objeto de detalles de la pantalla.

Bloqueo de activación de pantalla

Imagina lo siguiente: Estás en la cocina siguiendo una receta en tu tablet. Acabas de terminar de preparar los ingredientes. Tienes las manos sucias y vuelves a mirar el dispositivo para leer el siguiente paso. ¡Desastre! ¡La pantalla se puso negra! La API de Screen Wake Lock está aquí para ayudarte y permite que una PWA evite que las pantallas se atenúen, entren en suspensión o se bloqueen, lo que permite que los usuarios detengan, inicien, salgan y regresen sin preocupaciones.

// Request a screen wake lock
const wakeLock = await navigator.wakeLock.request();

// Listen for wake lock release
wakeLock.addEventListener('release', () => {
 console.log(`Screen Wake Lock released: ${wakeLock.released}`);
});
// Manually release the wake lock
wakeLock.release();

Teclado virtual

Los dispositivos táctiles, como teléfonos y tablets, ofrecen un teclado virtual en pantalla para que el usuario pueda escribir cuando los elementos de formulario de tu APW estén enfocados.

Con la API de VirtualKeyboard, tu PWA puede tener más control del teclado en plataformas compatibles con la interfaz navigator.virtualKeyboard.

  • Muestra y oculta el teclado virtual con navigator.virtualKeyboard.show() y navigator.virtualKeyboard.hide().
  • Indícale al navegador que cerrarás el teclado virtual por tu cuenta configurando navigator.virtualKeyboard.overlaysContent como true.
  • Conoce cuándo aparece y desaparece el teclado con el evento geometrychange.
  • Configura la política del teclado virtual en los elementos host de edición estableciendo contenteditable en auto o manual, con el atributo virtualkeyboardpolicy HTML. Una política te permite decidir si deseas que el navegador controle el teclado virtual automáticamente (auto) o que lo controle tu secuencia de comandos (manual).
  • Usa variables de entorno de CSS para obtener información sobre la apariencia del teclado virtual, como keyboard-inset-height y keyboard-inset-top.

Obtén más información sobre esta API en Control total con la API de VirtualKeyboard.