silphius/app/add-key-listener.js
2024-06-10 22:45:09 -05:00

49 lines
1.3 KiB
JavaScript

// Handle lame OS key input event behavior. See: https://mzl.la/2Ob0WQE
// Also "up" all keys on blur.
export default function addKeyListener(target, listener) {
let keysDown = {};
let keyUpDelays = {};
function setAllKeysUp() {
for (const i in keyUpDelays) {
clearTimeout(keyUpDelays[i]);
}
keyUpDelays = {};
for (const key in keysDown) {
listener({type: 'keyUp', payload: key});
}
keysDown = {};
}
function onBlur() {
setAllKeysUp();
}
function onKeyDown(event) {
const {key} = event;
if (keysDown[key]) {
if (keyUpDelays[key]) {
clearTimeout(keyUpDelays[key]);
delete keyUpDelays[key];
}
return;
}
keysDown[key] = true;
listener({type: 'keyDown', payload: key});
}
function onKeyUp(event) {
const {key} = event;
keyUpDelays[key] = setTimeout(() => {
delete keyUpDelays[key];
delete keysDown[key];
listener({type: 'keyUp', payload: key});
}, 20);
}
window.addEventListener('blur', onBlur);
window.addEventListener('keyup', onKeyUp);
target.addEventListener('keydown', onKeyDown);
return () => {
setAllKeysUp();
target.removeEventListener('keydown', onKeyDown);
window.removeEventListener('keyup', onKeyUp);
window.removeEventListener('blur', onBlur);
};
}