Files
msime-windows/windows
fanlusky 8b65243b11 perf(windows): 焦点激活与 worker 管道发布改为事件唤醒
切换焦点后,EnsureNamedpipeFocusSessionActivated 等 worker 管道回显 focus
token 时用 Sleep(1) 轮询,最长 150 ms。Sleep(1) 按系统时钟粒度向上取整(默认约
15.6 ms),而回显通常不到 1 ms 就到了,所以每次切换焦点都白等一个时钟周期。
冷激活、Server 重启或重连之后,IPC worker 线程没有管道时每 50 ms 才检查一次
新发布的句柄,回显又在管道里多躺最多 50 ms。两处都在宿主 UI 线程的首键路径上。

- 新增两个自动重置事件:worker 记下确认后 SetEvent(_workerAckEvent);
  PublishWorkerPipeHandleIfChanged 发布非空句柄后 SetEvent(_workerPipePublishedEvent)。
- 等确认的循环改为 WaitForSingleObject(ack, 剩余时间)。检查逻辑、令牌比对和
  150 ms 上限不变;每次唤醒都先重新检查,worker 在 release 写入之后才发信号,
  不会丢唤醒,残留信号只多一轮检查。与 Sleep 一样不泵消息,不会重入 TSF 回调。
- worker 无管道时改为 WaitForMultipleObjects({stop, published}, 50),stop 在
  下标 0 优先;50 ms 超时保留为兜底。
- 事件经新增的 BindNamedpipeWakeEvents 绑定到线程本地,UnbindNamedpipeFocusState
  一并清除。在 IPC 线程启动前创建、join 之后关闭;Deactivate 关闭前先解绑,
  其后的 _EndComposition 若再进等待循环会退回轮询,不会等已关闭的句柄。创建
  失败或等待失败时退回原来的 Sleep(1)。
- 不动 PeekNamedPipe 存活检查,也不用 timeBeginPeriod(会改宿主进程的全局状态)。
2026-09-27 17:43:43 +08:00
..

windows —— TSF 文本服务

水杉输入法在 Windows 上的前端:一个纯 TSF 方案的文本服务 DLL,注入宿主进程,负责按键预判、焦点与线程归属、composition 的 edit session 写入,以及与 Server 之间的命名管道协议。候选窗、工具栏、设置页和实际的候选计算都在 ../server/,本目录只做宿主适配。

产品介绍、安装和功能说明见仓库根目录的 README;本目录的代码地图、TSF/COM 硬约定和改动要求见 AGENTS.md。

构建

从仓库根目录配置,源码目录是本目录:

cmake -S windows -B windows/build -A x64 `
  -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT/scripts/buildsystems/vcpkg.cmake" `
  -DVCPKG_TARGET_TRIPLET=x64-windows-static
cmake --build windows/build --config Release --parallel
ctest --test-dir windows/build -C Release --output-on-failure

Win32 用 -A Win32 和 x86-windows-static;安装包两种架构都要。scripts/ 下是本机开发用的生成、构建、注册和签名脚本,从本目录运行。

引擎契约来自 ../engine/contracts/,是本仓的目录,普通检出就有。TSF 只引用这些头文件,不链接引擎运行库。