Skip to content

Commit

Permalink
Handle keydown not being a KeyboardEvent
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
CryZe committed Sep 27, 2022
1 parent 3d2f27e commit 26d1281
Showing 1 changed file with 14 additions and 8 deletions.
22 changes: 14 additions & 8 deletions crates/livesplit-hotkey/src/wasm_web/mod.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -26,7 +26,7 @@ pub type Result<T> = std::result::Result<T, Error>;
/// A hook allows you to listen to hotkeys.
pub struct Hook {
hotkeys: Arc<Mutex<HashMap<KeyCode, Box<dyn FnMut() + Send + 'static>>>>,
keyboard_callback: Closure<dyn FnMut(KeyboardEvent)>,
keyboard_callback: Closure<dyn FnMut(Event)>,
gamepad_callback: Closure<dyn FnMut()>,
interval_id: Cell<Option<i32>>,
}
Expand Down Expand Up @@ -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 a
// `select` sends a `keydown` event that is not a `KeyboardEvent`.
if let Ok(event) = event.dyn_into::<KeyboardEvent>() {
if !event.repeat() {
if let Ok(code) = event.code().parse() {
if let Some(callback) = hotkey_map.lock().unwrap().get_mut(&code) {
callback();
}
}
}
}
}) as Box<dyn FnMut(KeyboardEvent)>);
}) as Box<dyn FnMut(Event)>);

window
.add_event_listener_with_callback("keydown", keyboard_callback.as_ref().unchecked_ref())
Expand Down

0 comments on commit 26d1281

Please sign in to comment.