Cómo capturar claves con la API de Keyboard Lock

Proporciona una experiencia envolvente de pantalla completa para una variedad de casos de uso, incluidos sitios web interactivos, juegos y transmisión de aplicaciones o escritorios remotos.

Cada vez más usuarios pasan la mayor parte del tiempo en el navegador, por lo que los sitios web altamente interactivos, los juegos, la transmisión de escritorio remoto y la transmisión de aplicaciones se esfuerzan por brindar una experiencia envolvente de pantalla completa. Para ello, los sitios necesitan acceso a teclas especiales y combinaciones de teclas mientras están en modo de pantalla completa, de modo que se puedan usar para la navegación, los menús o los juegos. Algunos ejemplos de las teclas que pueden ser necesarias son Esc, Alt + Tab, Cmd + ` y Ctrl + N.

De forma predeterminada, estas claves no están disponibles para la aplicación web porque el navegador o el sistema operativo subyacente las capturan. La API de Teclado de bloqueo permite que los sitios web usen todas las teclas disponibles permitidas por el SO host (consulta Compatibilidad del navegador).

Ubuntu Linux se transmitió a una pestaña del navegador en Chrome para macOS (aún no se ejecuta en modo de pantalla completa).
El problema: Un escritorio remoto de Ubuntu Linux transmitido no se ejecuta en modo de pantalla completa y sin bloqueo de teclado activo, por lo que el sistema operativo anfitrión de macOS sigue capturando las teclas del sistema y la experiencia aún no es envolvente.

Cómo usar la API de Keyboard Lock

La interfaz Keyboard de la API de Keyboard proporciona funciones que activan o desactivan la captura de pulsaciones de teclas del teclado físico, además de obtener información sobre el diseño del teclado del usuario.

Requisitos

Hay dos tipos de pantalla completa disponibles en los navegadores modernos: la que inicia JavaScript a través de la API de Fullscreen y la que inicia el usuario a través de una combinación de teclas. La API de Keyboard Lock solo está disponible cuando está activa la pantalla completa iniciada por JavaScript. Este es un ejemplo de pantalla completa iniciada por JavaScript:

await document.documentElement.requestFullscreen();

Detección de atributos

Puedes usar el siguiente patrón para verificar si la API de Keyboard Lock es compatible:

if ('keyboard' in navigator && 'lock' in navigator.keyboard) {
  // Supported!
}

Cómo bloquear el teclado

El método lock() de la interfaz Keyboard muestra una promesa después de habilitar la captura de las pulsaciones de teclas de cualquiera o todas las teclas del teclado físico. Este método solo puede capturar claves a las que el sistema operativo subyacente les otorga acceso. El método lock() toma un array de uno o más códigos de teclas para bloquear. Si no se proporcionan códigos de teclas, se bloquearán todas las teclas. Hay una lista de valores de códigos de tecla válidos disponible en la especificación de Valores de código de TecladoEvent de eventos de la IU.

Cómo capturar todas las teclas

En el siguiente ejemplo, se capturan todas las pulsaciones de teclas.

navigator.keyboard.lock();

Captura de claves específicas

En el siguiente ejemplo, se capturan las teclas W, A, S y D. Capta estas teclas independientemente de los modificadores que se usen con la presión de tecla. Si se supone un diseño QWERTY de EE.UU., el registro de "KeyW" garantiza que W, Mayúsculas + W, Control + W, Control + Mayúsculas + W y todas las demás combinaciones de modificadores de teclas con W se envíen a la app. Lo mismo se aplica a "KeyA", "KeyS" y "KeyD".

await navigator.keyboard.lock([
  "KeyW",
  "KeyA",
  "KeyS",
  "KeyD",
]);

Puedes responder a las pulsaciones de teclas capturadas con eventos de teclado. Por ejemplo, este código usa el evento onkeydown:

document.addEventListener('keydown', (event) => {
  if ((event.code === 'KeyA') && !(event.ctrlKey || event.metaKey)) {
    // Do something when the 'A' key was pressed, but only
    // when not in combination with the command or control key.
  }
});

Cómo desbloquear el teclado

El método unlock() desbloquea todas las claves capturadas por el método lock() y muestra el resultado de forma síncrona.

navigator.keyboard.unlock();

Cuando se cierra un documento, el navegador siempre llama de forma implícita a unlock().

Demostración

Para probar la API de Keyboard Lock, ejecuta la demo en Glitch. Asegúrate de consultar el código fuente. Si haces clic en el botón para entrar a la pantalla completa que aparece a continuación, se iniciará la demostración en una ventana nueva para que pueda entrar en el modo de pantalla completa.

Consideraciones de seguridad

Una preocupación con esta API es que se podría usar para capturar todas las teclas y (junto con la API de Fullscreen y la API de PointerLock) evitar que el usuario salga de la página web. Para evitar esto, la especificación requiere que el navegador proporcione una forma para que el usuario salga del bloqueo del teclado, incluso si la API solicita todas las teclas. En Chrome, esta escotilla de escape es una presión prolongada (dos segundos) de la tecla Esc para activar la salida del bloqueo del teclado.

Agradecimientos

Joe Medley y Kayce Basques revisaron este artículo. Los autores de la especificación de bloqueo del teclado son Gary Kacmarcik y Jamie Walch. Imagen hero de Ken Suarez en Unsplash.