日期:2026-07-01
对照 /Users/ar/Projects/Taglauncher-doc/chat-history/codex-sessionhistory/2026-07-01-WindowServer会诊.md,以最新代码重新核查会诊中提到的 WindowServer / TextInput / 鼠标事件风险,拉上架构师和代码审核员判断还有哪些确实需要提前修复。
/Users/ar/Projects/Taglauncher/Users/ar/Projects/Taglauncher/srccodex/pro-custom-hotkeys-8.2.00ae3a93,tag v8.3.1-build20260701.2302src/Release/... 发布资料,未触碰。2026-07-01-WindowServer会诊.mdsrc/Apptag/QuickSearch.swiftsrc/Apptag/ApptagApp.swiftsrc/Apptag/ContentView.swiftsrc/Apptag/TagNavigationView.swiftsrc/Apptag/AppGridCollectionView.swiftsrc/Apptag/AppGridSupport.swiftsrc/Apptag/OverlayWindowController.swift0ae3a93、CODEGRAPH.md、会诊纪要和两个子 agent 只读复核。20260701.2029 的主要高危点归因为标签编辑时同一 NSEvent 被转发给 NSTextField.mouseDown,并列出 Quick Search / IME、外部点击、窗口置前、TagNavigation 阻塞循环等剩余风险。mouseDown 转发风险在当前源码已不成立;Quick Search / IME、外部点击关闭、重复置前、TagNavigation 阻塞循环仍有当前源码证据。src/Apptag/QuickSearch.swift:1706 的 doCommandBy 直接拦截 Up / Down / Return / Esc;src/Apptag/QuickSearch.swift:1735 的 keyDown 也直接处理同一组键。src/Apptag/ContentView.swift:141 的标签编辑路径已有 textView.hasMarkedText() guard。src/Apptag/ApptagApp.swift:1922 对任意 global mouseDown 发关闭请求;src/Apptag/ContentView.swift:894 关闭时清空 query/results/selection。src/Apptag/ContentView.swift:614 query 变化刷新结果;src/Apptag/QuickSearch.swift:823 / :855 每次 apply 都 NSApp.activate、makeKeyAndOrderFront、orderFrontRegardless;src/Apptag/QuickSearch.swift:1668 还有多次 delayed focus。mouseDown 事件循环。src/Apptag/TagNavigationView.swift:488 在 mouseDown 内 while !finished;src/Apptag/TagNavigationView.swift:510 只等 .leftMouseDragged/.leftMouseUp,nextEvent 为 nil 时继续循环。TextField + 非激活 overlay + 主动抢焦点组合。src/Apptag/AppGridSupport.swift:62 使用 SwiftUI TextField;src/Apptag/AppGridSupport.swift:117 setter 直接 prefix 截断;src/Apptag/OverlayWindowController.swift:232 overlay 是 .nonactivatingPanel。src/Apptag/AppGridCollectionView.swift:754 安装 local monitor;src/Apptag/AppGridCollectionView.swift:777 对非本窗口事件用 NSEvent.mouseLocation 映射;命中后可返回 nil。event.window === self.window。NSEvent 被手动转发给 NSTextField.mouseDown。src/Apptag/ContentView.swift:84 现在只 focusTextField();src/Apptag/ApptagApp.swift:2171 / :2175 是 focus-only,不再调用 container.mouseDown(with:) 或 tf.mouseDown(with:)。tag_editor_mouse_event_qa.sh PASS。src/Apptag/QuickSearch.swift 当前 Quick Search panel 是可 key panel;quick_search_launch_contract_qa.sh PASS。sendEvent 有点击兜底。quick_search_launch_contract_qa.sh PASS。用途:复查当前源码是否仍有标签编辑 mouseDown 回归、Quick Search 点击/回车启动合同,以及快速定位 IME / monitor / event loop 风险点。
前置条件:在 /Users/ar/Projects/Taglauncher/src 或仓库根目录运行;不需要启动 App,不会修改源码。
cd /Users/ar/Projects/Taglauncher/src
bash Scripts/tag_editor_mouse_event_qa.sh
验证结果:本轮输出 PASS Tag editor mouse event QA: text-field clicks focus without recursive mouseDown forwarding。
cd /Users/ar/Projects/Taglauncher/src
bash Scripts/quick_search_launch_contract_qa.sh
验证结果:本轮输出 PASS quick search launch contract。
cd /Users/ar/Projects/Taglauncher
rg -n "hasMarkedText|markedText|doCommandBy|keyDown\\(|addGlobalMonitorForEvents|nextEvent\\(" src/Apptag/QuickSearch.swift src/Apptag/ApptagApp.swift src/Apptag/TagNavigationView.swift src/Apptag/ContentView.swift
搜索关键词:WindowServer、CursorUIViewService、Quick Search IME、hasMarkedText、markedText、addGlobalMonitorForEvents、TagNavigation nextEvent、tag_editor_mouse_event_qa、quick_search_launch_contract_qa。
mouseDown 事件循环改成状态机,或先加最小退出条件。发布前建议优先做一个小修复批次:
mouseDown 循环增加兜底退出,或改为非阻塞事件状态机。