Files
openless/openless-all
b16950d13e fix(hotkey): Esc 取消改走独立通道——修复转写/润色期间按 Esc 停不下来 (#853)
* fix(hotkey): Esc 取消改走独立通道——修复转写/润色期间按 Esc 停不下来

#798 给 end_session 加了「转写 vs 取消」的 select! 赛跑,但取消信号本身
送不进来:hotkey bridge 线程为修 #468/#475 的 latch 竞态改成了串行
block_on,Hold 松手后 end_session 在 bridge 线程上同步跑完整段转写 +
润色,期间 Esc 的 HotkeyEvent::Cancelled 只能在同一条 channel 里排队。
流程跑完后才被取出,此时 phase 已回 Idle,cancel 变 no-op —— 用户按
Esc 毫无反应,必须干等转写完成。听写键为修饰键(默认 fn 等)时必现;
组合键用户不受影响(按键事件走 ComboHotkeyMonitor 的独立线程),这也是
#798 验证时没暴露的原因。

修法:把 Cancelled 从 HotkeyEvent 枚举拆出,Esc 在 tap/hook 回调里改发
独立的 Sender<()>,由专用 esc-cancel-bridge 线程消费并调 cancel_session
(纯同步快路径,不 await)。cancelled 旗标即时置位,end_session 的
select! 赛跑与润色流的 should_cancel 立即命中。macOS CGEventTap 与
Windows WH_KEYBOARD_LL 同步修改;Less Computer 修饰键 monitor 的 Esc
转发同样迁移。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(hotkey): esc-cancel-bridge 启动失败留 error 日志并补单元测试

- spawn_esc_cancel_bridge 线程创建失败时 log::error,避免 Esc 取消静默失效
- 新增 esc_cancel_bridge_loop 单元测试:Processing 阶段置 cancelled、
  录制快捷键期间跳过、重复信号幂等

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Chris233 <h-chris233@outlook.com>
2026-07-31 21:47:59 +08:00
..

OpenLess All-Platform

This is the current cross-platform OpenLess workspace.

App Directory

The runnable Tauri app lives in app/. The macOS build links a vendored C ASR engine (Open-Less/qwen-asr, forked from antirez/qwen-asr) tracked as a git submodule under app/src-tauri/vendor/qwen-asr/, so initialize submodules on first clone.

# First clone only — pull in vendored submodules
git submodule update --init --recursive

cd app
npm ci
npm run tauri dev

macOS Build

Use the project build script instead of calling tauri build directly:

cd app
INSTALL=0 ./scripts/build-mac.sh

Generated macOS artifacts:

  • app/src-tauri/target/release/bundle/macos/OpenLess.app
  • app/src-tauri/target/release/bundle/dmg/OpenLess_1.1.0_aarch64.dmg

For local install during development:

cd app
./scripts/build-mac.sh

Windows Build

The runnable Tauri app is still app/. Windows contributors should run a preflight before building so missing MSVC, Windows SDK, or MinGW tools fail with actionable messages.

cd app
powershell -ExecutionPolicy Bypass -File .\scripts\windows-preflight.ps1

MSVC Route

Use this route when Visual Studio Build Tools and the Windows SDK are installed. Open a Developer PowerShell, or call vcvars64.bat, then run:

cd app
npm ci
npm run tauri -- build

Required Visual Studio Installer components:

  • Microsoft.VisualStudio.Workload.VCTools
  • MSVC v143 x64/x86 build tools
  • Windows 10/11 SDK that provides kernel32.lib

If link.exe or kernel32.lib is missing, rerun:

powershell -ExecutionPolicy Bypass -File .\scripts\windows-preflight.ps1 -Toolchain msvc

GNU / MinGW Route

Use this route when MSVC/Windows SDK is unavailable. The app now lives under the no-space openless-all directory to avoid GNU/MinGW path quoting issues while generating import libraries. Use the helper script to keep the GNU build environment and target setup consistent.

cd app
scoop install rustup mingw
rustup toolchain install stable-x86_64-pc-windows-gnu
rustup target add x86_64-pc-windows-gnu
powershell -ExecutionPolicy Bypass -File .\scripts\windows-preflight.ps1 -Toolchain gnu
powershell -ExecutionPolicy Bypass -File .\scripts\windows-build-gnu.ps1

Generated GNU artifacts:

  • %TEMP%\openless-windows-gnu\src-tauri\target\x86_64-pc-windows-gnu\release\openless.exe
  • %TEMP%\openless-windows-gnu\src-tauri\target\x86_64-pc-windows-gnu\release\bundle\msi\OpenLess_*_x64_en-US.msi
  • %TEMP%\openless-windows-gnu\src-tauri\target\x86_64-pc-windows-gnu\release\bundle\nsis\OpenLess_*_x64-setup.exe

Hotkey Injection Gate

Use this gate before/after Windows hotkey changes when a physical keyboard regression is unavailable. It injects a dev/test-only hotkey click through the coordinator handle_pressed / handle_released path, asserts the log contains [coord] hotkey pressed, and cancels the dry-run session automatically.

cd app
npm run check:hotkey-injection

Windows Runtime Notes

  • Windows does not need the macOS Accessibility permission. Use Settings -> Permissions -> Global hotkey to inspect listener status.
  • Microphone permission is checked by opening a short-lived input stream, so a device-format query alone is not treated as permission granted.
  • Text insertion through Ctrl+V is treated as copy fallback unless the app can confirm insertion.

Release Signing

Tagged releases (v*-tauri) must be Developer ID signed and notarized so users can download and open the macOS app without manually removing quarantine attributes.

Required GitHub secrets:

  • APPLE_CERTIFICATE
  • APPLE_CERTIFICATE_PASSWORD
  • APPLE_ID
  • APPLE_PASSWORD
  • APPLE_TEAM_ID

Optional:

  • APPLE_PROVIDER_SHORT_NAME
  • KEYCHAIN_PASSWORD

Manual workflow runs can still produce ad-hoc signed test builds, but tagged macOS releases fail if signing/notarization secrets are missing.

Ignored Local Output

The following are intentionally local-only:

  • app/node_modules/
  • app/dist/
  • app/src-tauri/target/
  • app/src-tauri/gen/
  • .DS_Store