From 1d9132de3b7fe16b59b47611b94d70e3ad90e325 Mon Sep 17 00:00:00 2001 From: Joseph Montanaro Date: Tue, 12 Sep 2023 21:46:25 -0700 Subject: [PATCH] make hotkey configuration more timing tolerant --- todo.md => doc/todo.md | 0 src/ui/settings/Keybind.svelte | 57 +++++++++++++++++++--------------- 2 files changed, 32 insertions(+), 25 deletions(-) rename todo.md => doc/todo.md (100%) diff --git a/todo.md b/doc/todo.md similarity index 100% rename from todo.md rename to doc/todo.md diff --git a/src/ui/settings/Keybind.svelte b/src/ui/settings/Keybind.svelte index 8e3f3c9..79e16c6 100644 --- a/src/ui/settings/Keybind.svelte +++ b/src/ui/settings/Keybind.svelte @@ -7,42 +7,49 @@ const id = Math.random().toString().slice(2); const dispatch = createEventDispatcher(); - const modifierKeys = new Set(['Alt', 'AltGraph', 'Control', 'Fn', 'FnLock', 'Meta', 'Shift', 'Super', ]); + const MODIFIERS = new Set(['Alt', 'AltGraph', 'Control', 'Fn', 'FnLock', 'Meta', 'Shift', 'Super', ]); + + let listening = false; + let keysPressed = []; + + function addModifiers(event) { + // add modifier key if it isn't already present + if (MODIFIERS.has(event.key) && keysPressed.indexOf(event.key) === -1) { + keysPressed.push(event.key); + } + } + + function addMainKey(event) { + if (!MODIFIERS.has(event.key)) { + keysPressed.push(event.key); + + value.keys = keysPressed.join('+'); + dispatch('update', {value}); + event.preventDefault(); + event.stopPropagation(); + + unlisten(); + } + } function listen() { // don't re-listen if we already are if (listening) return; listening = true; - window.addEventListener('keyup', setKeybind, {once: true}); + window.addEventListener('keydown', addModifiers); + window.addEventListener('keyup', addMainKey); // setTimeout avoids reacting to the click event that we are currently processing - setTimeout(() => window.addEventListener('click', cancel, {once: true}), 0); + setTimeout(() => window.addEventListener('click', unlisten), 0); } - function setKeybind(event) { - // separate events fire for modifier keys, even when they are combined with a regular key - if (modifierKeys.has(event.key)) return; - - let keys = []; - if (event.ctrlKey) keys.push('Ctrl'); - if (event.altKey) keys.push('Alt'); - if (event.metaKey) keys.push('Meta'); - if (event.shiftKey) keys.push('Shift'); - // capitalize - keys.push(event.key); - - value.keys = keys.join('+'); - dispatch('update', {value}); + function unlisten() { listening = false; - window.removeEventListener('click', cancel, {once: true}); - event.preventDefault(); - event.stopPropagation(); - } - - function cancel() { - listening = false; - window.removeEventListener('keyup', setKeybind, {once: true}); + keysPressed = []; + window.removeEventListener('keydown', addModifiers); + window.removeEventListener('keyup', addMainKey); + window.removeEventListener('click', unlisten); }