Capturar teclas com a API Keyboard Lock

Ofereça uma experiência imersiva em tela cheia para diversos casos de uso, incluindo sites interativos, jogos e área de trabalho remota ou streaming de aplicativos.

Com cada vez mais usuários passando a maior parte do tempo no navegador, sites e jogos altamente interativos, streaming de área de trabalho remota e streaming de aplicativos se esforçam para fornecer uma experiência imersiva em tela cheia. Para isso, os sites precisam de acesso a teclas especiais e atalhos de teclado enquanto estão no modo de tela cheia, para que possam ser usados em navegação, menus ou jogos. Algumas teclas que podem ser necessárias são Esc, Alt + Tab, Cmd + ` e Ctrl + N.

Por padrão, essas chaves não estão disponíveis para o aplicativo da Web porque são capturadas pelo navegador ou pelo sistema operacional subjacente. A API Keyboard Lock permite que os sites usem todas as chaves disponíveis permitidas pelo SO do host. Consulte Compatibilidade do navegador.

O Ubuntu Linux fez streaming para uma guia do navegador no macOS Chrome (ainda não está em execução no modo de tela cheia).
O problema: uma área de trabalho remota Ubuntu Linux transmitida não é executada no modo de tela cheia e sem bloqueio de teclado ativo. para que as chaves do sistema ainda sejam capturadas pelo sistema operacional do host macOS, e a experiência não ainda é imersiva.

Como usar a API Keyboard Lock

A interface Keyboard da API Keyboard oferece funções que alternam a captura de pressionamentos de teclas no teclado físico, além de receber informações sobre o layout do teclado do usuário.

Pré-requisito

Há dois tipos de tela cheia disponíveis em navegadores modernos: iniciada por JavaScript pela API de tela cheia e iniciada pelo usuário por meio de um atalho de teclado. A API Keyboard Lock só fica disponível quando a tela cheia iniciada pelo JavaScript está ativa. Veja um exemplo de tela cheia iniciada por JavaScript:

await document.documentElement.requestFullscreen();

Detecção de recursos

Você pode usar o seguinte padrão para verificar se há suporte para a API Keyboard Lock:

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

Como bloquear o teclado

O método lock() da interface Keyboard retorna uma promessa depois de ativar a captura de pressionamentos de teclas para qualquer uma ou todas as teclas no teclado físico. Esse método só captura chaves com acesso pelo sistema operacional subjacente. O método lock() usa uma matriz de um ou mais códigos de tecla para bloquear. Se nenhum código de tecla for informado, todas as chaves serão bloqueadas. Uma lista de valores de códigos de chave válidos está disponível na especificação Valores de código de eventos de interface com eventos de interface.

Como capturar todas as chaves

O exemplo a seguir captura todos os pressionamentos de tecla.

navigator.keyboard.lock();

Como capturar chaves específicas

O exemplo a seguir captura as chaves W, A, S e D. Ele captura essas teclas, independentemente de quais modificadores são usados ao pressionar a tecla. Considerando um layout QWERTY EUA, o registro de "KeyW" garante que W, Shift + W, Control + W, Control + Shift + W e todas as outras combinações de modificadores com W sejam enviadas ao app. O mesmo se aplica a "KeyA", "KeyS" e "KeyD".

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

É possível responder aos pressionamentos de tecla capturados usando eventos de teclado. Por exemplo, este código usa o 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.
  }
});

Como desbloquear o teclado

O método unlock() desbloqueia todas as chaves capturadas pelo método lock() e retorna de forma síncrona.

navigator.keyboard.unlock();

Quando um documento é fechado, o navegador sempre chama unlock() implicitamente.

Demonstração

Você pode testar a API Keyboard Lock executando a demonstração no Glitch. Não se esqueça de conferir o código-fonte. Clicar no botão "Enter fullscreen" abaixo inicia a demonstração em uma nova janela para o modo de tela cheia.

Considerações de segurança

Uma preocupação com essa API é que ela pode ser usada para capturar todas as chaves e, junto com a API Fullscreen e a API PointerLock, impedir que o usuário saia da página da Web. Para evitar isso, a especificação exige que o navegador ofereça uma maneira de o usuário sair do bloqueio do teclado, mesmo que todas as teclas sejam solicitadas pela API. No Chrome, o pressionamento da tecla Esc é longo (dois segundos) para acionar uma saída do bloqueio do teclado.

Agradecimentos

Este artigo foi revisado por Joe Medley e Kayce Basques. A especificação "Bloqueio de teclado" é de Gary Kacmarcik e Jamie Walch (links em inglês). Imagem principal de Ken Suarez no Unsplash.