症状
在 Windows 端:
- 全屏游玩游戏(典型例子:Minecraft),或者把 Minecraft 放大到全屏时
- 触发 OpenLess 流式语音输入,capsule 输入提示框不会弹出
- 语音识别出的字符也不会落到游戏里
macOS 上同样的操作正常。
复现条件
- OS: Windows
- 游戏:Minecraft(Java / Bedrock 均报告)
- 游戏窗口模式:全屏 / 最大化
- OpenLess:流式语音输入开启
期望行为
至少 macOS 当前的体验:capsule 显示在游戏窗口之上,识别字符流式落到游戏聊天框(用户已按 T 打开聊天)。
根因分析(代码级 + Windows OS 机制)
按可能性排序:
1. Capsule overlay 在独占全屏(exclusive fullscreen)DirectX/OpenGL 应用之上无法绘制 ← 主要嫌疑
代码现状:`openless-all/app/src-tauri/src/coordinator.rs:4001-4034` 的 `show_capsule_window_no_activate` 用:
```rust
ShowWindow(hwnd, SW_SHOWNOACTIVATE)
SetWindowPos(hwnd, HWND_TOPMOST, ..., SWP_NOACTIVATE | SWP_SHOWWINDOW)
```
这是 Windows 标准 topmost。OS 级限制:
- 独占全屏(exclusive fullscreen)DirectX 应用接管整个显存合成路径,标准 Win32 topmost 窗口不会被绘制在它之上。
- borderless windowed fullscreen(无边框窗口化全屏)则属于普通 desktop 合成,topmost 可以正常叠加。
Minecraft 行为:
- Java 版默认是 borderless windowed(GLFW 实现)
- 但用户按 F11 / 设置切到真正的全屏 / 部分启动器 / 某些 mod 会切到 exclusive fullscreen
- Bedrock / Win10 edition 是 UWP,规则又不一样
macOS 不存在 exclusive fullscreen(所有全屏都是带 Spaces 的 borderless),所以 capsule 必然可见 —— 这就解释了平台差异。
2. UIPI(User Interface Privilege Isolation)阻挡 hotkey
代码现状:`openless-all/app/src-tauri/src/hotkey.rs:748-1003` 用 `SetWindowsHookExW(WH_KEYBOARD_LL, ...)`。
OS 级限制:低权限进程安装的 low-level keyboard hook 收不到高权限进程的按键。
- 若用户的 Minecraft 启动器以管理员身份运行(或 game 本身需要管理员)
- 而 OpenLess 是普通用户权限
- 则 OpenLess 完全收不到 hotkey edge → 录音根本不启动 → capsule 也不显示
3. SendInput 进了游戏窗口但落不到文本输入位置
代码现状:`openless-all/app/src-tauri/src/insertion.rs:388-428` 的 `windows_unicode::send_text` 用 `SendInput(KEYEVENTF_UNICODE)` 发 UTF-16 击键。
- Minecraft 用 GLFW,理论上接收 SendInput → 标准 Windows message queue 路径正常
- 但只有在 聊天框打开(用户按 T) 时字符才落到文本输入区
- 否则按键被游戏当作 movement / 物品栏 / 选项 hotkey 消化掉
这一项不应该是主因(用户应该会先开聊天框)但应排查。
诊断需要的数据
请用户提供:
- 游戏窗口模式:Minecraft 的 视频设置 → 全屏模式 当前是开还是关;通过 F11 切换的话切到哪种
- 是否以管理员身份运行:Minecraft 启动器和 OpenLess 各自的权限状态
- 日志文件:`%LOCALAPPDATA%\OpenLess\Logs\openless.log` —— 重点看:
- `[hotkey] Windows trigger pressed` 是否出现(验证假设 2)
- `[coord] session started` 是否出现(验证录音流程是否启动)
- `[coord] streaming_insert SUCCESS` 是否出现(验证识别完整流程)
修复方向
- (短期 / 文档):在 README / USAGE 中说明 Windows 独占全屏的限制,建议用户把游戏切到 borderless windowed fullscreen
- (短期 / 代码):在关键路径加 Windows 专属诊断日志(前台窗口标题、capsule 实际可见性、SendInput 返回值),让用户能给出更精确的复现数据
- (中长期):考虑接入 DirectX overlay(类似 Discord / MSI Afterburner 的方案),但工程量大、风险高,不在本 issue 范围
平台 / 环境
- OS: Windows
- 影响版本: 现行 beta 1.3.3 之前所有
- 不影响 macOS
cc @baiqing
症状
在 Windows 端:
macOS 上同样的操作正常。
复现条件
期望行为
至少 macOS 当前的体验:capsule 显示在游戏窗口之上,识别字符流式落到游戏聊天框(用户已按 T 打开聊天)。
根因分析(代码级 + Windows OS 机制)
按可能性排序:
1. Capsule overlay 在独占全屏(exclusive fullscreen)DirectX/OpenGL 应用之上无法绘制 ← 主要嫌疑
代码现状:`openless-all/app/src-tauri/src/coordinator.rs:4001-4034` 的 `show_capsule_window_no_activate` 用:
```rust
ShowWindow(hwnd, SW_SHOWNOACTIVATE)
SetWindowPos(hwnd, HWND_TOPMOST, ..., SWP_NOACTIVATE | SWP_SHOWWINDOW)
```
这是 Windows 标准 topmost。OS 级限制:
Minecraft 行为:
macOS 不存在 exclusive fullscreen(所有全屏都是带 Spaces 的 borderless),所以 capsule 必然可见 —— 这就解释了平台差异。
2. UIPI(User Interface Privilege Isolation)阻挡 hotkey
代码现状:`openless-all/app/src-tauri/src/hotkey.rs:748-1003` 用 `SetWindowsHookExW(WH_KEYBOARD_LL, ...)`。
OS 级限制:低权限进程安装的 low-level keyboard hook 收不到高权限进程的按键。
3. SendInput 进了游戏窗口但落不到文本输入位置
代码现状:`openless-all/app/src-tauri/src/insertion.rs:388-428` 的 `windows_unicode::send_text` 用 `SendInput(KEYEVENTF_UNICODE)` 发 UTF-16 击键。
这一项不应该是主因(用户应该会先开聊天框)但应排查。
诊断需要的数据
请用户提供:
修复方向
平台 / 环境
cc @baiqing