Capturar teclas com a API Keyboard Lock

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

Com cada vez mais usuários passando a maior parte do tempo no navegador, os sites, jogos, transmissões de desktop remoto e transmissões de aplicativos com recursos interativos avançados buscam oferecer uma experiência imersiva em tela cheia. Para isso, os sites precisam ter acesso a teclas especiais e atalhos de teclado enquanto estão no modo de tela cheia para que possam ser usados na navegação, nos menus ou em jogos. Alguns exemplos de 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 teclas disponíveis permitidas pelo SO do host (consulte Compatibilidade com navegadores).

O Ubuntu Linux foi transmitido para uma guia do navegador no Chrome para macOS (ainda não está em execução no modo de tela cheia).
O problema: um computador remoto Ubuntu Linux transmitido não em execução no modo de tela cheia e sem bloqueio de teclado ativo. Portanto, as teclas do sistema ainda são capturadas pelo sistema operacional do host do macOS e a experiência ainda não é imersiva.

Como usar a API Keyboard Lock

A interface Keyboard da API Keyboard oferece funções que alternam a captura de pressionamentos de teclas do 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. Confira um exemplo de tela cheia iniciada por JavaScript:

await document.documentElement.requestFullscreen();

Detecção de recursos

Use o seguinte padrão para verificar se a API Keyboard Lock é compatível:

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

Bloquear o teclado

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

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 dos modificadores usados com a tecla pressionada. Considerando um layout QWERTY dos EUA, o registro de "KeyW" garante que W, Shift + W, Control + W, Control + Shift + W e todas as outras combinações de teclas modificadoras 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 a 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() de forma implícita.

Demonstração

Para testar a API Keyboard Lock, execute a demonstração no Glitch. Confira o código-fonte. Clicar no botão "Entrar em tela cheia" abaixo inicia a demonstração em uma nova janela para que ela possa entrar no modo de tela cheia.

Considerações de segurança

Uma preocupação com essa API é que ela pode ser usada para capturar todas as teclas e (em conjunto 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, essa saída de emergência é um longo (dois segundos) pressionamento da tecla Esc para ativar a 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.