edit | blame | history | raw

Taglauncher WindowServer 预防收窄

日期:2026-07-02
项目:Taglauncher
会话:Coder3
主题:WindowServer 预防收窄

用户目标

用户确认按会诊建议继续做两项预防性收窄,顺序为:

  1. 先做 Usage Tips local monitor 事件来源收窄。
  2. 再做 App note 泡泡输入框 IME 风险收窄,并跑中文输入法真实输入相关的代码门禁。

本轮目标是最小范围提前降低 WindowServer / TextInput 风险,不重做已验收 UI,不生成新的视觉方案。

已完成事项

  • Usage Tips local mouse monitor 只处理同一 AppGrid 窗口的鼠标事件。
  • Usage Tips 坐标换算去掉跨窗口时基于 NSEvent.mouseLocation 的兜底,非本窗口事件直接返回 .zero
  • App note 泡泡编辑框从 SwiftUI TextField 改为 AppKit NSTextField 桥接。
  • App note 泡泡在 IME marked text 期间不覆盖、不截断、不提交文本,回车提交和 Esc 取消只在 marked text 结束后处理。
  • 新增 App note 泡泡输入静态 QA,并把 Usage Tips 同窗口收窄写进原有 QA。
  • 完整构建通过,生成 /Users/ar/Projects/Taglauncher/src/build/TagLauncher.app,构建号输出为 8.3.1 (20260702.0128)

关键决策

  • 不改 OverlayWindowController.nonactivatingPanel 行为,避免扩大行为变化。
  • App note 泡泡只替换输入控件内部实现,保留原泡泡布局、外观、备注长度上限和 Esc 取消语义。
  • Usage Tips 只收窄事件来源,不改变显示、关闭提醒、按钮和翻页行为。

核心事实 / 变更快照

  • 变更对象:Usage Tips local monitor 鼠标事件路由。
  • 变更前:local monitor 会在 self.window != nil 时继续处理事件,跨窗口坐标可用 NSEvent.mouseLocation 兜底换算。
  • 变更后:local monitor 必须满足 event.window === self.window;跨窗口事件不再用全局鼠标位置换算,直接返回 .zero
  • 范围边界:只影响 Usage Tips 鼠标事件吞噬范围,不影响 AppGrid 普通点击和 Usage Tips 同窗口点击。
  • 证据:bash Scripts/usage_tips_qa.sh PASS。
  • 变更对象:App note 泡泡编辑输入框。

  • 变更前:SwiftUI TextField(tr("appNote.placeholder"), text: limitedDraft) 通过 Binding setter 即时 prefix(maxAppNoteLength) 截断。
  • 变更后:AppBubbleNoteTextField 使用 AppKit NSTextField 桥接;marked text 期间不写回 SwiftUI binding,不截断,不执行回车提交 / Esc 取消。
  • 范围边界:最终提交仍由 TagDatabase.maxAppNoteLength 限制;未改变备注额度、备注保存路径和泡泡外观容器。
  • 证据:bash Scripts/app_note_bubble_input_qa.sh PASS;bash Scripts/macos14_availability_typecheck_qa.sh PASS;bash build.sh PASS。

文件变更

  • /Users/ar/Projects/Taglauncher/src/Apptag/AppGridCollectionView.swift
  • 收窄 Usage Tips local monitor 到本窗口事件。
  • Usage Tips host / view 坐标换算移除跨窗口全局鼠标位置兜底。
  • /Users/ar/Projects/Taglauncher/src/Apptag/AppGridSupport.swift

  • 新增 AppBubbleNoteTextField / AppBubbleNativeTextField
  • App note 泡泡编辑框改用原生 NSTextField 桥接。
  • marked text 期间保护 IME 组合输入,最终同步时再限制备注长度。
  • /Users/ar/Projects/Taglauncher/src/Scripts/usage_tips_qa.sh

  • 新增 Usage Tips local monitor 只消费本窗口事件的静态断言。
  • 新增 Usage Tips 坐标换算不得使用跨窗口 NSEvent.mouseLocation 兜底的静态断言。
  • /Users/ar/Projects/Taglauncher/src/Scripts/app_note_bubble_input_qa.sh

  • 新增 App note 泡泡输入 IME 安全静态 QA。
  • /Users/ar/Projects/Taglauncher/CODEGRAPH.md

  • 追加 windowserver_event_safety_qa.shapp_note_bubble_input_qa.sh QA 索引说明。

QA 结果

cd /Users/ar/Projects/Taglauncher/src
bash Scripts/app_note_bubble_input_qa.sh

结果:PASS app note bubble input QA。

cd /Users/ar/Projects/Taglauncher/src
bash Scripts/usage_tips_qa.sh

结果:PASS usage tips QA。

cd /Users/ar/Projects/Taglauncher/src
bash Scripts/windowserver_event_safety_qa.sh

结果:PASS windowserver event safety QA。

cd /Users/ar/Projects/Taglauncher/src
bash Scripts/tag_editor_mouse_event_qa.sh

结果:PASS Tag editor mouse event QA。

cd /Users/ar/Projects/Taglauncher/src
bash Scripts/quick_search_launch_contract_qa.sh

结果:PASS quick search launch contract。

cd /Users/ar/Projects/Taglauncher/src
bash Scripts/macos14_availability_typecheck_qa.sh

结果:PASS macOS 14.0 availability typecheck: arm64。

cd /Users/ar/Projects/Taglauncher/src
git diff --check

结果:PASS,无输出。

cd /Users/ar/Projects/Taglauncher/src
bash build.sh

结果:PASS,生成 /Users/ar/Projects/Taglauncher/src/build/TagLauncher.app,构建输出 TagLauncher 8.3.1 (20260702.0128)

cd /Users/ar/Projects/Taglauncher/src
bash Scripts/macos14_build_metadata_qa.sh

结果:PASS build metadata: LSMinimumSystemVersion=14.0 minos=14.0 arches=arm64

可复用命令 / Runbook

用途:复查本轮 WindowServer / TextInput 预防性收窄是否仍成立。

前置条件:

  • 项目源码目录为 /Users/ar/Projects/Taglauncher/src
  • 当前代码包含 Usage Tips 本窗口事件收窄与 App note 泡泡原生输入框桥接。
  • 不需要真实购买状态。

设置命令:

cd /Users/ar/Projects/Taglauncher/src
bash Scripts/usage_tips_qa.sh
bash Scripts/app_note_bubble_input_qa.sh
bash Scripts/windowserver_event_safety_qa.sh
bash Scripts/tag_editor_mouse_event_qa.sh
bash Scripts/quick_search_launch_contract_qa.sh
bash Scripts/macos14_availability_typecheck_qa.sh
git diff --check
bash build.sh
bash Scripts/macos14_build_metadata_qa.sh

验证步骤:

  • 所有 QA 输出 PASS。
  • bash build.sh 输出 App 构建成功,并生成 /Users/ar/Projects/Taglauncher/src/build/TagLauncher.app

清理 / 恢复命令:

  • 本 Runbook 不修改系统环境变量,不需要清理。
  • 若运行构建后只想删除本地构建产物,可手动删除 /Users/ar/Projects/Taglauncher/src/build/,但发布或验收前不建议删除。

搜索关键词:usage_tips_qa.shapp_note_bubble_input_qa.shWindowServerApp note bubbleNSTextFieldhasMarkedTextNSEvent.mouseLocationevent.window === self.window

未决问题

  • 本轮没有做真实 GUI 中文输入法人工录屏验证;仅完成代码层防线、静态 QA、typecheck 和完整构建。
  • 工作区仍保留此前已有的 Release 文档脏改动,本轮未触碰。

后续建议

  • 用户空闲时可人工打开备注泡泡,用中文输入法输入候选词、回车确认、Esc 取消,观察是否仍出现卡死或输入中断。
  • 若后续还有 WindowServer 日志,可优先对照本记录中的两个风险点确认是否复发。