From dd69747cb82f771f7844fb5769a8aaad2b701c1d Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Sat, 25 Jul 2026 18:15:51 +0100 Subject: [PATCH] fix(hotkeys): capture times out instead of waiting forever MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A combo another app already registered is consumed by Windows and delivered to that app — our keydown listener never fires. The capture therefore sat on "Press combo…" indefinitely with no feedback, which is exactly what a user sees when they try to re-assign a taken combo. Worse, while armed the capture preventDefaults every keystroke, so an abandoned capture froze the app's keyboard until Esc. 10 s timeout that restores the button and explains the likely cause: the combo never reached us because another app owns it. Co-Authored-By: Claude Opus 4.8 --- js/app.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/js/app.js b/js/app.js index aed6e39..00bb14d 100644 --- a/js/app.js +++ b/js/app.js @@ -7708,7 +7708,20 @@ async function init() { const original = btn.textContent; btn.textContent = 'Press combo… (Esc to cancel)'; + // A combo already owned by another app via RegisterHotKey is + // swallowed by Windows — it is delivered to that app, never to us, + // so the capture would wait forever with no explanation. It also + // preventDefaults every keystroke while armed, so an abandoned + // capture freezes the app's keyboard. Time out and say why. + const timer = setTimeout(() => { + finish(true); + toast('No combo captured. If you did press one, another app ' + + 'already owns it — Windows routes it there and we never ' + + 'see it. Try a different combo.', 'warning'); + }, 10000); + function finish(restore) { + clearTimeout(timer); btn.dataset.capturing = ''; btn.classList.remove('is-capturing'); document.removeEventListener('keydown', onKey, true);