Geralmente, não se espera que um aplicativo que manipulou um evento KeyPress
manipule o evento KeyRelease
subsequente. Se o usuário pressionar uma tecla, alternar para outro aplicativo e, em seguida, liberar a chave, a mudança de foco deverá ocorrer quando solicitada, não deverá ser adiada até que o usuário tenha liberado a chave.
A arquitetura do X11 para manipular eventos de entrada é bem simples: ou o evento foi capturado por um cliente, caso em que o cliente recebe o evento ou o evento não foi capturado; nesse caso, o cliente que atualmente possui o evento foco recebe o evento. Não há nenhuma disposição para despachar eventos KeyRelease
separadamente com base em qual cliente recebeu o evento KeyPress
.
Um exemplo em que seria claramente errado redirecionar KeyRelease
eventos para o cliente que recebeu o KeyPress
com modificadores. Em uma mudança de foco, se um modificador for pressionado, ele permanecerá pressionado. O evento KeyRelease
é enviado quando o modificador não está mais pressionado. Embora possa fazer sentido enviar KeyRelease
eventos para todos os modificadores deprimidos em uma perda de foco e enviar os eventos KeyPress
correspondentes para a janela recém-focalizada, isso não seria um relatório preciso da entrada real do usuário, que seria especialmente disruptivo para mudanças de foco entre widgets do mesmo aplicativo.
Outro exemplo em que o comportamento do X11 está claramente correto e sua proposta de reencaminhar eventos de pressionamento de tecla seria errada é com alterações de foco entre os widgets do mesmo aplicativo. Seria errado enviar eventos espúrios se o aplicativo se importar com essa chave específica sem se importar com qual widget estava focado. Mas, se o aplicativo se importar com qual widget recebe o evento KeyRelease
, esse evento definitivamente deve ser enviado para o widget que tem o foco no momento.
A maioria dos aplicativos tem ações acionadas por eventos de pressionamento de tecla, não por eventos de lançamento de chave. Quando um evento faz com que um botão seja pressionado, espera-se que o efeito do botão seja acionado no momento da impressão, não no momento da liberação. Seria uma experiência estranha do usuário se os eventos que causassem o fechamento de uma janela tivessem um comportamento diferente.
Um exemplo em que é claramente a coisa certa deixar o foco ser transferido para outra janela quando uma tecla pressionada causou o fechamento de uma janela é manter a tecla Esc pressionada para sair de vários diálogos caixas. Seria perturbador se um aplicativo exigisse liberar a tecla Esc a ser liberada para fechar uma janela.
No cenário que você descreve, é claramente o aplicativo Firefox / JavaScript que está fazendo algo errado. A maioria das interfaces de teclado é baseada em pressionamentos de teclas, não em liberações de chave. Em particular, é pressionando Enter que supostamente faz com que algo aconteça, não liberando ele. Se um aplicativo reage a um evento de lançamento de chave, o ônus está nele para lidar com situações em que ele recebe um evento KeyRelease
sem ter recebido um KeyPress
correspondente de uma maneira sensata.
Os cliques do mouse são um pouco diferentes porque há muitas situações em que se espera que uma interface reaja a eventos de lançamento, como arrastar e soltar ou eventos que dependem da duração de um clique. Mesmo assim, um aplicativo geralmente não deve reagir a um evento ButtonRelease
se não obtiver o ButtonPress
correspondente.