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 aplicativos ou de área de trabalho remota.

Com cada vez mais usuários passando a maior parte do tempo no navegador, sites interativos, jogos, streaming de área de trabalho remota e streaming de aplicativos se esforçam para oferecer 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 para navegação, menus ou jogos. Alguns exemplos de teclas que podem ser necessárias são Esc, Alt + Tab, Cmd + ` e Ctrl + N.

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

Ubuntu Linux transmitido para uma guia do navegador no Chrome do macOS (ainda não em modo de tela cheia).
O problema: uma área de trabalho remota do Ubuntu Linux transmitida não está sendo executada no modo de tela cheia e não tem o bloqueio de teclado ativo. Por isso, as teclas do sistema ainda são capturadas pelo sistema operacional host do macOS, e a experiência 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 mais recentes: iniciada por JavaScript usando a API Fullscreen e iniciada pelo usuário usando um atalho de teclado. A API Keyboard Lock só está disponível quando a tela cheia iniciada por JavaScript está ativa. Veja 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 do sistema operacional subjacente. 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 KeyboardEvent de eventos de IU.

Capturando todas as teclas

O exemplo a seguir captura todas as teclas pressionadas.

navigator.keyboard.lock();

Como capturar teclas específicas

O exemplo a seguir captura as teclas W, A, S e D. Ele captura essas teclas, independentemente de quais modificadores são usados com o pressionamento de tecla. Supondo 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 modificadores de teclas com W sejam enviadas ao app. O mesmo se aplica a "KeyA", "KeyS" e "KeyD".

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

Você pode responder às teclas pressionadas 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 teclas capturadas pelo método lock() e retorna de forma síncrona.

navigator.keyboard.unlock();

Quando um documento é fechado, o navegador sempre chama unlock() de maneira implícita.

Demonstração

Para testar a API Keyboard Lock, execute esta demonstração. Confira o código-fonte. Clique no botão "Entrar no modo de tela cheia" abaixo para abrir a demonstração em uma nova janela e entrar no modo de tela cheia.

Considerações sobre segurança

Uma preocupação com essa API é que ela pode ser usada para capturar todas as teclas e, em conjunto com as APIs Fullscreen e 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 de teclado, mesmo que todas as teclas sejam solicitadas pela API. No Chrome, essa saída de emergência é um pressionamento longo (dois segundos) da tecla Esc para acionar uma saída do bloqueio de teclado.

Agradecimentos

Este artigo foi revisado por Joe Medley e Kayce Basques. A especificação do bloqueio de teclado foi criada por Gary Kacmarcik e Jamie Walch.