xiaozhu1337 and fanlusky
9c0f6da9be
feat(windows): add opt-in per-app Vim Escape mode ( #737 )
...
* feat(windows): add opt-in per-app Vim Escape mode
* fix(windows): 改用 config.toml 的 vim_mode_apps 并移除 yaml-cpp
TSF DLL 会注入所有宿主进程,约定保持 /Zc:threadSafeInit- 且不加全局构造器;
yaml-cpp 带命名空间级 std::string 数组和线程安全局部静态,违背这一约定。
配置改为 [input] vim_mode_apps = [...],由 DLL 内的小型解析器读取,
沿用 config.toml 的时间戳缓存;键写入出厂模板与工作配置,升级合并保留用户值。
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-09 16:59:05 +08:00
fanlusky
9f5572c525
fix(build): 所有 MSVC 目标显式按 UTF-8 编译源文件
...
#548 修了 ngram,同类问题还有几处:源文件或头文件是无 BOM 的 UTF-8,
目标却没有 /utf-8,在代码页 936 的系统上注释会吞掉换行。
- ui:Controls.h 让 msimeui 与各 demo 单独构建失败,/utf-8 设为 PUBLIC
- server/tests/portable:input_key_policy.h 让 MSVC 构建失败
- engine test_windows_ipc_contract、tests/pipe-probe、windows/tests:C4819
- windows DLL:此前只靠 fmt 的 INTERFACE 选项带来 /utf-8,改为显式设置,
否则 L"“" 等宽字符标点会在去掉 fmt 后静默变成乱码
2026-09-30 15:37:13 +08:00
fanlusky
18cf3efe0a
refactor(windows): 引入按键失败策略与本地重同步
...
新增 DeferredKeyFailurePolicy.h:把「按键为什么没能应用」映射成四种代价,
Stale(只丢这颗键)、Offline(离线原始通道,丢键并吞掉队列,保留本地组合)、
Resync(管道健康,但本地组合与 Server 可能不一致)、Transport(传输坏了或
状态未知,走完整重置)。纯函数,不依赖 TSF/COM,配套 tests/deferred_key_failure_policy.cpp。
新增 _RequestLocalResync:复用本地重置闸门取消组合,保持「先重置再排空」的
顺序,但不轮换 focus token、不关任何管道;闸门重新打开时在同一个 token 上补发
HideCandidateWnd,让 Server 清掉自己的组合(闸门关着时取消路径发出的 Hide 会被
挡下,所以必须补发)。重同步期间不清 _workerCommitReady,否则 WM_IpcReconnect
会把一次重同步等成 150 ms 超时并升级成完整重置。
_ResetSessionAfterFailure 统一处理失败后的会话丢弃:清空延迟队列(队列里的键
是按即将丢弃的组合分类的,一律吞掉,既不交还宿主也不重发),保留退格长按
守卫(#347),再按类别触发重置;重置期间把投影设为空组合,重置结束且队列为空
时释放投影,健康路径(包括 Excel 首键的同步排空)不会被残留的屏障挡住。
非按键路径里原本走完整传输重置、但管道其实没坏的几处改走重同步:OnEndEdit 的
组合属性检查与 EndComposition 失败、OnSetFocus 文档不匹配、WM_CheckGlobalCompartment
切换提交失败、_PostServerTextDelivery 投递失败。
2026-09-27 18:50:07 +08:00
fanlusky
ab58b10cdc
refactor(windows): 按职责拆分 CompositionProcessorEngine.cpp
...
CompositionProcessorEngine.cpp 有 3000 行,预编辑缓冲、按键表与
preserved key、输入模式与标点、虚拟键判定全挤在一个文件里。按职责拆成
以下几个翻译单元:
- CompositionProcessorEngine.cpp:_AddTextProcessorEngine、构造/析构、
SetupLanguageProfile、预编辑缓冲与光标(AddVirtualKey 到
GetCandidateList)、SetupConfiguration、语言栏按钮、
CMetasequoiaIME::CreateInstance/ComLessCreateInstance/GetComModuleName、
候选编号范围与默认字体
- CompositionProcessorEngine_Modes.cpp:中英文、标点、全半角 compartment
的读写与回调、SendCaretStateSwitchEvent、外部关闭键盘时的提交,以及
标点表、成对/嵌套标点和智能标点映射
- CompositionProcessorEngine_PreservedKeys.cpp:按键表、preserved key 的
设置/注册/资格/动作、OnPreservedKey、XPreservedKey 和 InitKeyStrokeTable
- CompositionProcessorEngine_KeyClassify.cpp:IsVirtualKeyNeed、
IsVirtualKeyNeedForFreshComposition 及其用到的按键表、候选键和数字范围
判定
纯搬移,不改行为:函数体、注释和格式都没动。匿名命名空间里的辅助函数、
CCaretStateSwitchEditSession 和智能标点映射表各自只被一个新文件用到,原样
留在该文件的匿名命名空间,不需要内部头文件,也没有新增全局构造器或函数内
静态变量。
用脚本比对了原文件与拆分后全部文件的非空、非 #include 行多重集:没有缺
失的行,差异只有新文件的文件头注释。可用 git diff --color-moved 复核。
2026-09-27 17:39:28 +08:00
fanlusky
a3739fc528
refactor(windows): 按职责拆分 MetasequoiaIME.cpp
...
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 复核。
2026-09-27 17:39:11 +08:00
fanlusky
9c1c4b82b2
refactor(windows): 按职责拆分 KeyEventSink.cpp
...
KeyEventSink.cpp 有 3100 多行,同步按键判定、延迟按键队列与回放、输入模式
热键全挤在一个文件里。按职责拆成以下几个翻译单元:
- KeyEventSink.cpp:_IsKeyEaten、ConvertVKey、_IsKeyboardDisabled、退格
长按与 CapsLock 处理、直通字符统计,以及 ITfKeyEventSink 各回调
(OnSetFocus、OnTestKeyDown、OnKeyDown/_DispatchKeyDown、OnTestKeyUp、
OnKeyUp、OnPreservedKey/_DispatchPreservedKey)和 sink 的注册/注销
- KeyEventSink_DeferredKeys.cpp:延迟按键屏障与容量、预测状态投影、恢复
前缀、_ClassifyDeferredKeyDown,以及入队、清空、完成、重试、丢弃歧义键、
排空调度和 Server 不可用回退
- KeyEventSink_Hotkeys.cpp:mintty 的裸 Shift 键盘钩子、裸修饰键武装、
组合键与修饰键松开热键匹配、_QueueInputHotkey
- KeyEventSinkInternal.h:上述文件之间共享的声明,只给
KeyEventSink*.cpp 包含
纯搬移,不改行为:函数体、注释和格式都没动。原来在匿名命名空间里、现在
要跨文件用的函数(SegmentEditFunction、CaptureIpcModifiers、
IsEnglishInputModeToggle、IsTranslationCommitShortcut、
IsCharacterSetInputModeToggle、PostOwnerMessageWithSyncFallback、
IsShiftVk)仍定义在 KeyEventSink.cpp,改放进 key_event_sink_detail 命名
空间并在内部头文件里声明;只被一个文件用到的仍留在该文件的匿名命名空间。
THIRDPARTY_NEXTPAGE/THIRDPARTY_PREVPAGE 宏和本来就是 inline 的
VKeyFromVKPacketAndWchar 原样挪进内部头文件。唯一的非搬移改动是
PostOwnerMessageWithSyncFallback 的默认实参从定义挪到了头文件里的声明上。
没有新增全局构造器或函数内静态变量。
用脚本比对了原文件与拆分后全部文件的非空、非 #include 行多重集:除上述
函数签名外,差异只有新增的声明、命名空间包装、using 指令、#pragma once
和文件头注释。可用 git diff --color-moved 复核。
2026-09-27 17:38:47 +08:00
Jia Sui
ffcd1aee28
feat: 输入统计(DLL 采集、Server 聚合存储与设置页展示)
...
- windows: 三上屏出口 + OnTestKeyDown 直通字符采集,修复半角数字恒零
- engine: 统计 Web 消息契约(statsRequest/statsResponse)
- server: 统计管道接收、聚合、SQLite 存储、保留策略与每日自动清理
- ui-html: 设置页「统计」模块(卡片、热图、明细、开关、清理)
- docs: PRIVACY / README 改为内置可选统计
2026-09-20 19:08:16 +08:00
fanlusky
a7779d2b05
refactor(engine): 将 engine 从 submodule 内嵌为仓内一等组件
...
`vendor/MetasequoiaImeEngine` submodule 改为 `engine/` 目录,导入的是
product-lock.json 原本钉住的提交 c810d201,逐文件核对过 blob,因此这是一次
搬迁而不是引擎升级。引擎自己的嵌套 submodule(googlepinyinime-rev、utfcpp、
miniaudio)按各自 gitlink 一并展开,来源与提交见 engine/UPSTREAM.md。
Windows 专门化裁掉了不属于本产品的部分:whisper.cpp 与本地推理 provider、
macOS 示例宿主、整个 dictionary/ 建库流水线、上游 CI 与 release-please 配置。
词库仍按 product-lock.json 在构建时取发布产物。
引擎不再进 product-lock.json:没有 gitlink 就没有可比对的东西,锁里写一个上游
commit 等于宣称这棵树仍等于上游,而第一个 Windows 专门化改动落地时这句话就假了。
verify-contracts / verify-checkout 随之移除,verify-published 保留。
CI 与工具链:引擎源码并入根 scripts/format.sh(删掉引擎自己的那份,避免两套排除
列表分叉);引擎 voice.yml 里的 silero_vad.onnx 摘要校验移到本仓 lock job;
engine-bump-triage 工作流与其测试删除;gitsubmodule 的 dependabot 频率由 daily
改为 monthly。
README、README.en、AGENTS.md、CONTRIBUTING、docs/product-release.md 及各子目录
文档同步说明新的位置与边界。
2026-09-12 03:40:48 +08:00
Evan
edb2074d7c
test(ipc): make fallback policy independently executable ( #307 )
2026-09-10 08:04:47 +09:00
Evan
96eb1bb2a4
test(ipc): lock down fallback result semantics ( #306 )
...
* fix(ipc): distinguish definite local fallback
* test(ipc): lock down fallback result semantics
2026-09-10 08:00:15 +09:00
AaGMix
e9a2c91214
feat(installer): include release PDB symbols
2026-09-07 02:10:38 +08:00
Evan Hu
87e842f6a3
build(windows): TSF、Server 与设置程序开启 /W4
...
/W4 已经是本仓的既有约定——ui/ 的五个 target 和 server/ 的四个辅助可执行文件都在用。漏掉的恰好是三个最大的:注入到 Chrome、QQ、Office 等宿主进程里的 TSF DLL,拥有全部网络调用、WebView2 宿主与皮肤加载的 Server 主进程,以及设置程序。这三个此前都跑在默认的 /W3 上。
暂不加 /WX:存量告警要先在 Windows 上读完并清掉,在那之前把告警变成错误只会逼出一堆 /wd 抑制。/permissive- 同样留到能在 Windows 上构建验证的后续改动,本次改动无法在本机编译验证这一项。
2026-09-06 18:11:37 +09:00
Evan Hu
373f8d1473
refactor: collapse the duplicated submodules into one vendor/ directory
...
Windows, Server and UiHtml each carried their own gitlink to MSIME-Engine, all three pinned to the same commit, and Server carried a gitlink to MSIME-UI that is now the ui/ component. Git only reads the root .gitmodules, so the nested ones had to go regardless.
The engine and the two third-party dependencies now live once at vendor/MetasequoiaImeEngine, vendor/opencc and vendor/cpp-pinyin. Server reaches them through MSIME_VENDOR_DIR and builds ui/ as an out-of-tree subdirectory; the Windows tip's relative contract includes gained the extra level; the ui-html contract sync and the Server env/table generators follow the engine to its new location.
2026-09-06 02:27:52 +09:00
Evan Hu
253b068984
refactor: move the Windows TSF frontend under windows/
...
Preparation for folding Server, UI, UiHtml, Installer, ImeLog and TsfEditControl into this repository. The Windows tip's own sources, build files and local build scripts move under windows/ so every component sits at the same level. Product-level files stay at the root: the lock, the release manifest, the shared CI scripts, the integration tests, the docs and the Engine submodule.
2026-09-06 02:24:27 +09:00