Skip to content

fix(selection-polish): 選區潤色預覽確認按鈕偶發無反應 - #1045

Draft
leonoxo wants to merge 1 commit into
Open-Less:betafrom
leonoxo:fix/selection-polish-preview-confirm-beta
Draft

fix(selection-polish): 選區潤色預覽確認按鈕偶發無反應#1045
leonoxo wants to merge 1 commit into
Open-Less:betafrom
leonoxo:fix/selection-polish-preview-confirm-beta

Conversation

@leonoxo

@leonoxo leonoxo commented Sep 9, 2026

Copy link
Copy Markdown

摘要

圈選潤色(選區潤色)在 macOS 上「確認並替換」偶爾沒反應:點了按鈕後沒有貼上、窗口也没動靜,再點就完全無效。排查後是四個問題疊加,本 PR 針對選區潤色 apply 路徑逐一處理(不碰 dictation 全域 insert、不加 AX WRITE、不做貼上後自動驗證)。

根因

  1. 預覽窗 show 搶焦點show_selection_polish_previewwindow.show() + set_focus()(tao 層 makeKeyAndOrderFront + NSApp.activate,已核對 tao 源碼),把 OpenLess 推成 frontmost;原 app 丟前台後,不少編輯器的選區直接被清,之後 confirm 的 reactivate/validate 就「有時」失敗。
  2. 失敗即殺 session:confirm 任何 Errfail_if_activeFailed + 隱藏預覽,用戶剛編輯的內容直接丟掉,表象就是「點確認沒反應」。
  3. reactivate 固定 120ms:部分 app(Electron、自繪窗口)恢復 key window 需要更久,固定 sleep 一次就核 pid 會偶發把「還在恢復中」誤判為「恢復失敗」。
  4. 前端 busy 卡死:預覽窗複用(hide 不卸載組件),上一輪 confirm/cancel 後 busy 停留 true,下一輪兩個按鈕全 disabled——即使後端恢復正常,按鈕也點不動。

修復

  • 預覽窗改 Nonactivating NSPanel(與膠囊/QA 同手法):to_panel() 後 styleMask 先讀再 OR NonactivatingPanel 位(set_style_mask 是全量替換,直接 set 會丟掉 titled/resizable),set_level(3) + FullScreenAuxiliary | CanJoinAllSpaces 可疊全屏 app;show 改主線程 orderFrontRegardless,不 makeKey、不激活 app;hide 也統一派發回主線程(NSPanel 不可從 worker 線程操作)。
  • confirm 失敗分流:session 已失效(Cancelled/InvalidState/InvalidArgument/Busy)才結算失敗並隱藏;瞬時平台錯誤(焦點恢復/目標複核抖動)回退 Preview 保持可重試,編輯內容不丟。fail_if_active 加相位保護:只結算 Capturing/Preview/Applying,已 Completed 的不再被誤標 Failed(complete 與 fail 判斷之間的窄窗口 race)。
  • reactivate 改輪詢:80ms × 4 輪,每輪補一次 activate_app_by_pid(幂等),pid 一穩定立刻返回;仍未恢復則明確失敗,不向偶然持有焦點的 app 盲寫。
  • 前端selection-polish-preview:shown 事件到達時復位 busy/error 再載入資料。

驗證

  • cargo check/test -p openless-core:全綠(含契約測試改名 transient_platform_failure_keeps_the_preview_retryable,斷言瞬時失敗後 session 保持可重試、不 cancel 不隱藏)。
  • 新窗口代碼已用同版本依賴(tauri 2.11.5 / tauri-nspanel v2 / objc2 0.5.2)的獨立 crate 編譯驗證通過;src-tauri 整樹本地無法 check(qwen3-asr-rs 的 MLX/Metal 需要完整 Xcode,CI 用 submodules: recursive 可編過),此 PR 不觸及該路徑。
  • 前端 tsc + 71 個前端測試全綠。
  • macOS 實機行為(預覽不搶焦點、可編輯、失敗可重試)建議在完整 Xcode 環境或 CI 上跑一次選區潤色 e2e 確認。

相容

  • DirectReplace 預設模式、dictation 全域 insert()、AX 唯讀策略均未改動。
  • 非 macOS 平台保持原 show()/set_focus() 路徑不變。

圈選潤色的「確認並替換」偶爾沒反應,根因鏈有四個,分別處理:

1. 预览窗 show 抢焦点:show_selection_polish_preview 走 window.show() +
   set_focus()(tao 层 makeKeyAndOrderFront + NSApp.activate),把 OpenLess
   推成 frontmost;原 app 丢前台后编辑器的选区被清,之后 confirm 的
   reactivate/validate 就「有时」失败。预览窗改成与胶囊/QA 同手法的
   Nonactivating NSPanel(to_panel + styleMask 先读再 OR NonactivatingPanel
   位——set_style_mask 是全量替换;level 3 + FullScreenAuxiliary/CanJoinAllSpaces
   叠全屏 app),show 走主线程 orderFrontRegardless,不 makeKey、不激活 app。
2. 失败即杀 session:confirm 任何 Err 都 fail_if_active → Failed + 隐藏预览,
   用户刚编辑的内容直接丢,只剩「点确认没反应」。分流:session 失效
   (Cancelled/InvalidState/InvalidArgument/Busy)才结算失败并隐藏;
   瞬时平台错误(焦点恢复/目标复核抖动)回退 Preview 保持可重试。
   fail_if_active 加相位保护:只结算 Capturing/Preview/Applying,已
   Completed 的不再被误标 Failed(complete 与 fail 之间的窄窗口)。
3. reactivate 固定 120ms:部分 app(Electron、自绘窗口)恢复 key window
   需要更久,固定 sleep 一次就核 pid 会偶发误判「恢复失败」。改成
   80ms x 4 轮询,每轮补一次 activate(幂等),pid 稳定立刻返回。
4. 前端 busy 卡死:预览窗复用(hide 不卸载组件),上一轮 confirm/cancel
   后 busy 停留 true,下一轮两个按钮全 disabled。「shown」事件到达时
   复位 busy/error。

验证:cargo check/test openless-core(含契约测试
transient_platform_failure_keeps_the_preview_retryable)全绿;
src-tauri 本机因缺 Metal 工具链(qwen3-asr-rs 需要完整 Xcode)无法整树
check,新窗口代码已用同版本依赖(tauri 2.11.5 / tauri-nspanel v2 /
objc2 0.5.2)的独立 crate 编译验证通过;前端 tsc + 71 个前端测试全绿。
macOS 实机行为(预览不抢焦点、confirm 重试)需要 CI(submodules: recursive)
或本机装完整 Xcode 后验证。
@appergb

appergb commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

抱歉,我们写得很清楚:目前正在进行 2.0 的优化,所以暂不接受任何 PR。如果你希望 PR 能继续推进并成功完成,可能需要等我们完全迁移到 2.0 的新后端、新前端之后,再针对这个问题进行解决。

@H-Chris233

Copy link
Copy Markdown
Collaborator

抱歉,我们写得很清楚:目前正在进行 2.0 的优化,所以暂不接受任何 PR。如果你希望 PR 能继续推进并成功完成,可能需要等我们完全迁移到 2.0 的新后端、新前端之后,再针对这个问题进行解决。

我先合你的,再合ta的,就这么简单

@Open-Less Open-Less deleted a comment from chatgpt-codex-connector Bot Sep 9, 2026
@leonoxo
leonoxo marked this pull request as draft September 10, 2026 06:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants