From 9b2f65fe71c9e6cc4d41250f789683a37d20bcdb Mon Sep 17 00:00:00 2001 From: baiqing Date: Thu, 30 Apr 2026 19:26:31 +0800 Subject: [PATCH] fix: harden Windows hotkey release handling --- .github/workflows/release-tauri.yml | 4 +++- openless-all/app/src/App.tsx | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release-tauri.yml b/.github/workflows/release-tauri.yml index 3db6d1d2..bcf5f42d 100644 --- a/.github/workflows/release-tauri.yml +++ b/.github/workflows/release-tauri.yml @@ -319,7 +319,9 @@ jobs: name: 'OpenLess ${{ github.ref_name }}' draft: false prerelease: false - generate_release_notes: true + # Matrix jobs all upload assets to the same release. Generate notes once + # so macOS, Windows, and Linux jobs do not duplicate the release body. + generate_release_notes: ${{ matrix.platform == 'macos-latest' }} files: | openless-all/app/src-tauri/target/release/bundle/dmg/*.dmg openless-all/app/src-tauri/target/release/bundle/macos/*.app.tar.gz diff --git a/openless-all/app/src/App.tsx b/openless-all/app/src/App.tsx index eeb9d697..3d1a376c 100644 --- a/openless-all/app/src/App.tsx +++ b/openless-all/app/src/App.tsx @@ -60,8 +60,14 @@ export function App({ isCapsule }: AppProps) { useEffect(() => { if (!isTauri || os !== 'win') return; + const pressedKeys = new Map(); const forwardKey = (event: KeyboardEvent) => { if (!isWindowHotkeyCandidate(event)) return; + if (event.type === 'keydown' && event.key !== 'Escape') { + pressedKeys.set(event.code, event.key); + } else if (event.type === 'keyup') { + pressedKeys.delete(event.code); + } void handleWindowHotkeyEvent( event.type as 'keydown' | 'keyup', event.key, @@ -69,11 +75,29 @@ export function App({ isCapsule }: AppProps) { event.repeat, ).catch(error => console.warn('[window-hotkey] forward failed', error)); }; + const releasePressedKeys = () => { + if (pressedKeys.size === 0) return; + const pending = Array.from(pressedKeys.entries()); + pressedKeys.clear(); + for (const [code, key] of pending) { + void handleWindowHotkeyEvent('keyup', key, code, false).catch(error => + console.warn('[window-hotkey] release fallback failed', error), + ); + } + }; + const releaseOnHidden = () => { + if (document.visibilityState === 'hidden') releasePressedKeys(); + }; window.addEventListener('keydown', forwardKey, true); window.addEventListener('keyup', forwardKey, true); + window.addEventListener('blur', releasePressedKeys); + document.addEventListener('visibilitychange', releaseOnHidden); return () => { window.removeEventListener('keydown', forwardKey, true); window.removeEventListener('keyup', forwardKey, true); + window.removeEventListener('blur', releasePressedKeys); + document.removeEventListener('visibilitychange', releaseOnHidden); + releasePressedKeys(); }; }, [os]);