MetasequoiaIME.cpp 有 3000 多行,激活/停用生命周期、按键路径的 edit session 请求、Worker Pipe 读线程和消息窗口处理全挤在一个文件里。按职责 拆成以下几个翻译单元: - MetasequoiaIME.cpp:Server 拉起辅助、CreateInstance、构造/析构、焦点 会话与 composition epoch 校验、本地会话重置、候选 presenter 延迟清理、 QueryInterface/AddRef/Release、ActivateEx/Deactivate、 _WakeServerIfNeeded/_NoteKeyEventIpcFailure 和 ITfFunctionProvider 系列 - MetasequoiaIME_AsyncRequests.cpp:标点、智能标点、延迟应用文本几个 edit session 及其 _Request*EditSession,待取的 Server 候选,异步按键 请求表(_PostAsyncKeyRequest/_TakeAsyncKeyRequest/_ClearAsyncKeyRequests) 和 _ClearPendingIpcRequests - MetasequoiaIME_IpcWorker.cpp:IpcWorkerThread,以及把它收到的上屏、 语音快照和 compartment 切换交给 TSF 线程的令牌表 - MetasequoiaIME_WindowProc.cpp:CMetasequoiaIME_WindowProc 及其用到的 状态快照发送、CommitCandidateAndContinue edit session,还有主题注册表 监听与语言栏图标刷新 - MetasequoiaIMEInternal.h:上述文件之间共享的声明,只给 MetasequoiaIME*.cpp 包含 纯搬移,不改行为:函数体、注释和格式都没动。原来在匿名命名空间里、现在 要跨文件用的 NextWindowMessageToken 仍定义在 MetasequoiaIME.cpp,改放进 metasequoia_ime_detail 命名空间并在内部头文件里声明; CONNECT_NAMEDPIPE_RETRY_INTERVAL_MS 常量挪进内部头文件的同一命名空间。 只被一个文件用到的仍留在该文件的匿名命名空间。_bareShiftHookOwner 这个 thread_local 和 #pragma comment 仍只在 MetasequoiaIME.cpp。没有新增全局 构造器或函数内静态变量。 用脚本比对了原文件与拆分后全部文件的非空、非 #include 行多重集:没有缺 失的行,差异只有新增的声明、命名空间包装、using 指令、#pragma once 和文 件头注释。可用 git diff --color-moved 复核。
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 只引用这些头文件,不链接引擎运行库。