From 1e8df26fa2695b7d2c396567bbd094d28229383b Mon Sep 17 00:00:00 2001 From: Christopher Serr Date: Tue, 27 Sep 2022 19:28:08 +0200 Subject: [PATCH] Handle `keydown` not being a `KeyboardEvent` Despite all sorts of documentation claiming that `keydown` events pass you a `KeyboardEvent`, this is not actually always the case in browsers. At least in Chrome selecting an element of an `input` sends a `keydown` event that is not a `KeyboardEvent`. --- crates/livesplit-hotkey/src/wasm_web/mod.rs | 22 +++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/crates/livesplit-hotkey/src/wasm_web/mod.rs b/crates/livesplit-hotkey/src/wasm_web/mod.rs index 1203aa65..dfe1299b 100644 --- a/crates/livesplit-hotkey/src/wasm_web/mod.rs +++ b/crates/livesplit-hotkey/src/wasm_web/mod.rs @@ -1,6 +1,6 @@ use crate::KeyCode; use wasm_bindgen::{prelude::*, JsCast}; -use web_sys::{window, Gamepad, GamepadButton, KeyboardEvent}; +use web_sys::{window, Event, Gamepad, GamepadButton, KeyboardEvent}; use std::{ cell::Cell, @@ -26,7 +26,7 @@ pub type Result = std::result::Result; /// A hook allows you to listen to hotkeys. pub struct Hook { hotkeys: Arc>>>, - keyboard_callback: Closure, + keyboard_callback: Closure, gamepad_callback: Closure, interval_id: Cell>, } @@ -80,15 +80,21 @@ impl Hook { let window = window().ok_or(Error::FailedToCreateHook)?; let hotkey_map = hotkeys.clone(); - let keyboard_callback = Closure::wrap(Box::new(move |event: KeyboardEvent| { - if !event.repeat() { - if let Ok(code) = event.code().parse() { - if let Some(callback) = hotkey_map.lock().unwrap().get_mut(&code) { - callback(); + let keyboard_callback = Closure::wrap(Box::new(move |event: Event| { + // Despite all sorts of documentation claiming that `keydown` events + // pass you a `KeyboardEvent`, this is not actually always the case + // in browsers. At least in Chrome selecting an element of an + // `input` sends a `keydown` event that is not a `KeyboardEvent`. + if let Ok(event) = event.dyn_into::() { + if !event.repeat() { + if let Ok(code) = event.code().parse() { + if let Some(callback) = hotkey_map.lock().unwrap().get_mut(&code) { + callback(); + } } } } - }) as Box); + }) as Box); window .add_event_listener_with_callback("keydown", keyboard_callback.as_ref().unchecked_ref())