小莫 and fanlusky
ab0c14e1bb
fix(server): 兼容社区皮肤的共享基底 ( #1003 )
...
* fix(server): 兼容社区皮肤的共享基底
* fix(server): 共享基底的选中与悬停色跟随清单覆盖后的配色
- selected / hover 按上游 resolve 规则从覆盖后的 accent / text 派生,非十六进制写法退回基底原色
- system 并入共享基底表,校验与适配只用 FindSharedBase 一处判定
- 皮肤样例校验、schema 文档与 niya-demo 注释同步接受共享基底
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-16 20:56:06 +08:00
HowGeGe and fanlusky
1671c3a467
fix(engine): recognize complete umlaut aliases in quanpin ( #994 )
...
* fix(engine): recognize complete umlaut aliases in quanpin
* refactor(engine): 移除九键输入
九键会话只有引擎公共 Session 门面在用,Server 与 TSF 都没有接入。删掉
NineKeySession、Session 的九键入口与 SessionSnapshot::nine_key_spellings,
以及对应测试和注释。
* fix(engine,server): ü 别名共用一条归一规则,入库与纠错不再产出查不到的键
- 新增 quanpin::is_jqxy_v_alias / canonical_umlaut_spelling,替换 canonical_syllable
与 to_google_spelling 里各自手抄的别名表,normalize_umlaut_aliases 也改用它。
- 纠错表生成器与运行时生成式空间不再从 jqxy+v 别名派生纠错键(nvan -> jvan 之类),
手误只纠到 u 的标准写法;重新生成 autocorrect_table.h。
- 个人词库新写入的拼音词、设置页导入的全拼按词库写法入库(xvan -> xuan、lue -> lve),
否则查询归一后永远查不到;被替换的旧词保留原键,旧行仍可删除。
- 双拼音节集统一排除 jqxy+v 别名,round-trip 检查不再特判。
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-16 20:48:33 +08:00
Jia Sui and fanlusky
93f95d1245
fix(engine): emoji / 颜文字查询精确命中优先于前缀命中 ( #989 )
...
* fix(engine): emoji 查询精确命中优先于前缀命中 (#988 )
* fix(engine): 颜文字查询同样精确命中优先于前缀命中 (#988 )
* fix(engine): emoji / 颜文字精确提级只认全拼,并合并为单次排序查询
- 双拼下原始码只按目录顺序参与前缀命中,不再精确提级:小鹤 xl 精确命中简拼键时会压过展开后的 xiang。
- 颜文字只有全拼精确命中提级,简拼精确命中不提级:单音节条目的简拼只有一个字母,打 k 时会整批排到前面。
- 两级查询合并为每个查询码一条 SQL(精确行在 LIMIT 之前),语句只 prepare 一次,循环抽到 local_database 的 query_ranked_entries 共用。
- server 回归测试不再断言 ku 多个精确条目之间的目录顺序。
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-16 20:17:01 +08:00
Lu Fan(SonnyCalcr)
53649d9d12
feat(server,ui,ui-html): 新增实验性的 Direct2D 设置窗口 ( #999 )
...
* feat(ui): 动画时钟、渲染剔除与文本框扩展,并优化 msimeui 性能
- 新增 Animation.h:cubic-bezier 缓动、Tween、颜色插值,Window 提供
RequestAnimationFrame / GetFrameTime,动画帧随显示刷新率推进
- Window 可选 DirectComposition 渲染(含不透明模式以支持 ClearType)、
双击按下、捕获丢失时结束按压、悬停刷新、可关闭销毁时退出消息循环
- Scene 把滚轮交给光标下最内层可滚动元素并逐级冒泡
- DeviceResources:裁剪栈驱动的离屏剔除、按帧回收的笔刷缓存、SVG 栅格缓存
- ScrollViewer 可配置外观与平滑滚动;Popup 支持阴影通道与出现动画;
卡片阴影缓存抽成可复用的 ShadowCache
- TextBox 支持 SetText、密码掩码、多行滚动、字重/字间距/行高与外观设置
- 调试日志默认关闭(MSIMEUI_DEBUG_LOG=1 才写文件),不再在每次点击和
TSF GetTextExt 时打开文件
- 字体回退在 CJK/emoji 映射之后保留系统回退,缺字不再显示方框
- 新增动画与剔除单元测试
* feat(server): 新增实验性的 Direct2D 设置窗口
设置窗口可通过 appearance.settings_ui_backend 选择渲染方式:默认 webview2,
d2d 为实验性的 msimeui 原生实现(server/src/settings/native/),1:1 复刻
网页设置页,包括侧栏切换时竖向高亮条的滑动动画。
- 两个前端共用同一套 webview 契约消息与 HandleClientMessage,配置读写
映射仍只在 settings_app.cpp
- 切换渲染方式后设置进程自动以新方式重新打开;--d2d / --webview2 可临时指定
- 新配置项写入出厂模板与开发配置,UiBackendPolicy 与测试同步更新
- METASEQUOIA_IME_SETTINGS_INSTANCE 允许开发版与已安装的设置窗口并存
- 更新 ui-backends 文档与 server/AGENTS.md
* feat(ui-html): 外观页新增设置窗口渲染方式选项
2026-10-16 16:13:13 +08:00
chr331 and fanlusky
1c3bd7cb83
feat(server,ui-html,windows): 支持自定义“输入状态切换”中的快捷键 ( #985 )
...
* fix(windows): 支持标点切换快捷键改绑与取消绑定
* fix(shortcut): 对齐虚拟键并处理语音与窗口快捷键冲突
* fix(ui-html): 绑定标点快捷键前提示应用快捷键占用
* fix(ui-html): 仅对已知快捷键冲突提示确认
* feat(shortcuts): 支持自定义输入状态切换快捷键
* fix: keep shortcut editor buttons on one row
* fix(shortcuts): 限定输入状态快捷键为 Ctrl 组合
* fix: clarify shortcut override and punctuation lock behavior
* perf(server,windows): 提前筛选输入状态快捷键
* fix(windows,server,ui-html): 修正输入状态快捷键的兼容与保存问题
- windows: 未协商 InputStateShortcuts 时回退到旧的 Ctrl+Shift+E KeyEvent,
新 DLL 配旧 Server 时英文候选快捷键不再失效
- windows: 全角快捷键与标点快捷键一样可在待处理按键后排队,不再漏给应用
- windows: Server 不可用时排队的英文候选切换按 FUNCTION_CANCEL 离线回放,
不再丢弃其后的按键
- server: 非字符串配置值不再以 "!invalid" 作为 binding 发给设置页
- server: 仅三个输入状态快捷键路径强制回传配置快照;去掉 worker 中与
reader 重复的协商检查;抽出 InputStateShortcutViews 去除重复转换
- ui-html: 保存后 5 秒未收到快照则恢复编辑器并提示重试
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-16 03:31:19 +08:00
Jia Sui and fanlusky
9beab473f4
fix(windows,server): 提交键慢响应改为分片让出等待,不再丢字或冻结宿主 ( #982 )
...
* fix(windows,server): 提交键慢响应改为分片让出等待,不再丢字或冻结宿主
* fix(windows): 提交回复轮询不阻塞宿主,补齐标点顶候选路径并保持结算顺序
- 标点顶高亮候选(WM_AsyncPunctuationCommit 无预取文本)也在处理函数里分片取回复,
edit session 不再在宿主 UI 线程上阻塞 300 ms
- 轮询改为不阻塞:先查缓存、PeekNamedPipe,有帧才以零超时读,不再每片阻塞 16 ms
- 定时器只重派已开始等待的请求,按请求 id 升序结算,较新的提交排在仍在等的旧提交之后
- 处理函数取到 TransportUnavailable 时直接按歧义丢键并重置,不再交给 edit session
- 已在等回复的提交键在同一焦点下被组合纪元取代时按 DeliveryAmbiguous 处理,避免两端分叉
- 回复缓存淘汰不再淘汰刚写入的条目;CachePendingReply 与提交回复缓存共用一份逻辑
- 停用时显式 KillTimer(TIMER_COMMIT_REPLY_POLL);windows/AGENTS.md 同步新的提交预算
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-16 02:48:58 +08:00
HowGeGe and fanlusky
64fdc775f0
fix(settings): preserve mouse capture during WebView drags ( #979 )
...
* fix(settings): preserve mouse capture during WebView drags
* fix(server): 设置窗口鼠标抓取丢失时补发抬起
把鼠标转发的抓取状态机从 settings_app.cpp 拆到 settings_mouse_input,
只做决策不调 Win32,测试直接链接它,不再在 configure 时切源码文本。
- WM_CAPTURECHANGED 时给仍按着的键补发抬起,标题栏拖动、
Alt+Tab、系统弹窗抢走抓取后页面不会卡在按下状态
- 抓取期间吞掉 WM_MOUSELEAVE,最后一个键抬起后再重新登记离开跟踪
- 隐藏或关闭设置窗口前释放抓取
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-16 01:56:02 +08:00
Jia Sui and fanlusky
d414268b5f
[Feat] U 模式重构为部件拆字反查 ( #973 )
...
* feat(engine,server,windows,ui-html,installer): U 模式重构为部件拆字反查 (#971 )
把 U 模式从 Unicode 十六进制码位输入改成部件拆字反查:Shift+U 后输入各
组成部分的拼音连写(晶 = ririri)即可出字,候选上反显注音。
- 引擎:新增 local_modes/radical_query(前缀匹配、字频降序),数据表
engine/radical/decomposition.txt 与生成脚本;LocalInputMode::Unicode
改为 Radical;删除 unicode_query。
- Server:g_radical_mode_triggered + IsRadicalCompositionActive + 候选分发,
用 cpp-pinyin 反显注音;删除 Unicode 码位路径。
- 前端 TSF:删除 U 模式的十六进制/数字特例与影子预判,按普通组合处理。
- 配置:utility.unicode_mode 改为 utility.radical_mode。
- 部署:assets 登记 radical_decomposition,安装器与 CI 拷表。
数据来源 mirtlecn/rime-radical-pinyin (GPL-3.0),授权见 engine/radical/NOTICE.md。
* feat(server): U 模式反显拼音改为带调风格(jīng)
* fix(server,installer): 修复 U 模式 CI(拆字表打包夹具与 clang-format)
* fix(engine,server): 修正 U 模式按键错位、重复候选与配置迁移
- Server 在 U 模式不再吞掉撇号、分号、斜杠、大写字母等键:TSF 已把它们记进按键缓冲,
吞掉又不重同步会让两侧串和光标错位。照常插入,含非 a-z 的码查不出候选
- 拆字查询全码命中排在仅前缀命中之前,同一个字的几种拆法只出一次
- 升级合并把旧键 utility.unicode_mode 的值带到 utility.radical_mode,读取时也兜底旧键
- 生成脚本只收汉字,重建拆字表去掉 abc 码下的 51 行数字、字母与符号
- 开着 U 模式时在后台预热拆字表与 cpp-pinyin 词典,避开首个按键的冷加载
- Server 按会话的 RuntimePaths 查拆字表,删掉走全局数据目录的便捷重载
- cpp-pinyin 初始化合并到 utils/hanzi_pinyin,设置页导入注音共用;U 模式与快捷短语的收键分支合并
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-16 01:01:18 +08:00
luo jiyin and fanlusky
f62b383851
fix(server): 适配 OpenAI 推理模型请求参数 ( #968 )
...
* fix(server): 适配 OpenAI 推理模型请求参数
OpenAI 请求使用 max_completion_tokens。推理模型省略 temperature,并增加输出上限。
增加请求 JSON 回归测试。DeepSeek 与自定义服务保持原有参数。
Refs #882
* fix(server): 修复 OpenAI 配置测试参数
设置页探测与 AI 联想共用 token 字段选择规则。
增加 OpenAI、DeepSeek、SiliconFlow 和自定义服务的请求 JSON 测试。
Refs #882
* fix(server): 增加 OpenAI 推理模型配置探测额度
设置页为 OpenAI 推理模型预留 32 个输出 token。
其他模型和服务商保持原有探测额度,并补充 JSON 断言。
Refs #882
* refactor(server): 明确配置探测请求函数名称
将 BuildChatRequestBody 改为 BuildChatProbeRequestBody。
更新设置页调用点和请求 JSON 测试。
Refs #882
* fix(server): 适配 AI 翻译的 OpenAI 推理模型参数
* fix(server): OpenAI 推理模型降低推理强度并放宽超时
默认 medium 推理常超过 8 秒,AI 联想与翻译会静默失败。
推理模型显式发送 reasoning_effort: low,超时与 DeepSeek thinking 一致用 30 秒;
设置页探测带上同样的参数。合并三处重复的推理请求判断。
Refs #882
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-15 22:48:04 +08:00
Jia Sui and fanlusky
2f7335be3e
统计增加首词命中率 ( #963 )
...
* feat(engine): webview 契约给统计概览增加首词命中率字段并支持 null 分支
* feat(server,ui-html): 统计新增首词命中率(决策点记录、stats v2 迁移与设置页展示)
* fix(server): 首词命中计数补日语标点排除与并发迁移复查
* fix(ui-html): 统计卡片改用自适应列宽,避免长数字被省略号截断
* fix(server,installer): 修复首词命中率随附测试在 CI 的失败
三条 server 用例是首词命中率改动新加、但从未跑绿:RawDb 在迁移用例里对尚不存在的库开只读写连接,补上 SQLITE_OPEN_CREATE;09-19 写了一次次选,按契约它是一次真实测量(0%),断言却要求 nullopt,改为断言 0.0,并把 nullopt 覆盖移到迁移用例(total==0 的那天)。安装器 preserve-user-data 从 stats_pipe.cpp 取库名,而 EnsureStatsStoreOpen 连同 stats.db 字面量已挪到 stats_candidate_capture.cpp,改到新位置。
* fix(server,ui-html): 首词命中率写库移出按键路径,修正迁移与统计口径
- 选词计数改由后台 SerialTaskRunner 写库,标点收尾与选词路径不再同步等 SQLite 锁
- 迁移以表结构为准,不再被版本号挡住;缺列时在 IMMEDIATE 事务里逐列补齐
- 标点在日期入口上收尾时按实际上屏的首条候选计数
- 五笔四码唯一自动上屏不计入;多段造词任一段非首位即不算命中
- 只有选词计数的日线不算打字日,不影响天数、日均与连续天数
- 卡片复用 formatFirstWordRatio 并展示累计命中率,概览复用 DailyRow::FirstWordRatio
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-15 22:09:50 +08:00
e56bfabdf2
feat(server,ui-html): AI 联想候选徽标支持切换 🤖 / 🐳 ( #948 )
...
* feat(server,ui-html): AI 联想候选徽标支持切换 🤖 / 🐳
AI 联想候选的来源角标此前硬编码为 🤖 ,用户无法更改。按固定排位徽标
(#463)的既有做法把它做成可配置项 appearance.candidate_ai_badge_style,
取值 "robot"(🤖 ,出厂默认)或 "whale"(🐳 )。
- 默认值保持 🤖 不变,升级不改变默认观感
- 与固定排位徽标一致,配置里存枚举名而不是字面 emoji,TOML/日志/diff
里不出现图形字符;新增样式只改白名单与展示层映射
- 非法取值一律回退到出厂 🤖 ,手改 TOML 写错不会让 AI 候选失去来源标识
- 展示层新增纯函数 AiSuggestionBadge(style),沿用既有 badge 字段通道,
D2D 与 WebView2 两个后端同时生效,不新增渲染路径
- 配置改动经既有 ConfigChanged → WM_APPLY_IME_CONFIG 链路即时生效,
无需重启输入法进程
- 出厂模板 config.default.toml 与开发配置 config.toml 同步补齐,
避免升级时用户选择被 MergeConfigIntoTemplate 静默丢弃
验证:
- server/tests/portable(Linux,g++,无 vcpkg):57 test(s), 0 failure(s)
- ui-html settings:vitest 167 passed,tsc --noEmit 通过,vite build 通过
- clang-format 18.1.8 --dry-run --Werror --style=file:改动文件全部通过
- scripts/ci/check-developer-paths.sh 通过;sync-contracts.py --check 通过
* fix(server): 补齐 IsValidCandidateAiBadgeStyle 的跨编译单元声明
ime_config_appearance.cpp 是独立编译单元,无法看到定义在 ime_config.cpp
里的 IsValidCandidateAiBadgeStyle,MSVC 报 C3861。补上 ime_config_internal.h
里的声明——IsValidCandidateFixedBadgeStyle 等同类校验函数都声明在那里。
* refactor(server,ui-html): AI 徽标样式改为单一映射表并精简测试
- AiSuggestionBadgeGlyph 作为样式到字形的唯一映射,配置层白名单
IsValidCandidateAiBadgeStyle 直接查它,新增样式不会两边漂移
- 测试去掉与首条断言重复的一行和恒真的 cloud 断言,改为检查映射表
对已知/未知样式的判定
- 设置页描述写明两种样式对应的 emoji
---------
Co-authored-by: Caiyi Liao <216114941+cxk1993@users.noreply.github.com >
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-15 02:44:27 +08:00
時崎 ギャラクシー and fanlusky
1b512c31d2
fix(server): 外部皮肤只在声明支持的布局与主题下生效 ( #946 )
...
* fix(server): 外部皮肤只在声明支持的布局与主题下生效
皮肤用 supports.layouts / supports.themes 声明适用范围。D2D 后端只 Load 不校验,横排皮肤在竖排也会被套用,退化成一张裸卡片;工具栏与光标徽标同样绕过这份声明。
把判定收成 CandidateSkinCatalog::LoadSupported,两个候选窗后端、工具栏、光标徽标四处共用,避免再出现某个使用方漏查。光标徽标的调色板缓存键补上布局,切换布局后徽标才会跟着回退。
补 LoadSupported 的用例:布局不支持、主题不支持、四种组合都声明、manifest 不可用。
* fix(server): 换布局时同步刷新工具栏,D2D 候选窗回退到 fluent
外部皮肤可能只声明部分布局,换布局后皮肤是否生效会变;工具栏跟随候选窗皮肤,
ApplyConfiguredCandidateWindowLayout 现在也重套 D2D 工具栏主题,WebView2 工具栏页面变了才重新导航。
D2D 候选窗在外部皮肤不生效或读不出来时,几何、配色与阴影都按 fluent 处理,
与 WebView2 端注入 fluent CSS 一致,不再拿外部皮肤 ID 去匹配内置分支。
光标徽标复用已解析的主题;注释改为回退 fluent;测试补上正常皮肤的对照断言,
并清理按进程号建的临时目录。
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-15 02:29:08 +08:00
Jia Sui and fanlusky
1499027f04
fix(engine,server): 光标落在拼音首单元内部不再收起候选窗 ( #940 )
...
* fix(engine,server): 光标落在拼音首单元内部不再收起候选窗
quantized_prefix_end() 把光标 floor 到完整单元边界后,prefix_end==0 同时表示「真串首」与「首单元内部」。后者被 Server 的 IsCaretPrefixEmpty 当成串首,候选窗整窗收起(全拼 nihaoya 选你好后剩 ya 左移即消失)。
floor 结果为 0 且 caret>0(首单元内部)时改返回 raw.size(),落回整串解码;prefix_end()==0 当且仅当 caret==0,只有真串首才隐藏。segment_raw_boundaries() 与 #187「前缀只切完整单元」的契约不变。
* fix(engine,server): 首单元内部的光标向上取整到首单元末尾
上一提交让首单元内部的光标落回整串解码,prefix_end() 因此报告整串已解码,
与实际光标位置不符:Server 选词时 caret_prefix_selection 为假,不复位组合
光标,造词后剩余串带着旧光标位置;首单元与后续单元的取整方向也不一致。
改为向上取整到首单元末尾(只有一个单元时即整串)。prefix_end() == 0 仍当且
仅当 caret == 0,前缀选词走正常的光标复位路径。同步更新引擎与
input_key_policy.h 中描述旧规则的注释和相应测试。
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-15 01:37:58 +08:00
Lu Fan(SonnyCalcr)
e46294308d
fix: CS2 / Dota 2 / 三角洲行动等游戏里的输入法兼容(加载、候选、翻页、独占全屏、启动崩溃) ( #925 )
...
* fix(installer): TSF DLL 改装到系统目录,CS2 等 Trusted Mode 游戏里可以切出输入法
CS2 的 Trusted Mode 只放行位于系统目录且有代码签名的第三方 in-proc DLL,
装在 Program Files 下的 DLL 会被拒绝加载,游戏里切不出输入法。
x64 DLL 改装到 System32\IME\MetasequoiaIME\msime_v*,x86 装到 SysWOW64 下同名目录,
语言配置图标随之放到两处根目录;升级时清掉旧版留在 Program Files 的版本目录。
* fix(windows): CS2、Dota 2 不理会 UI-less 声明,照常显示候选窗
起源 2 引擎的 Valve 游戏以 UI-less 激活 TSF,但只替白名单里的输入法绘制候选。
我们据声明收起了自己的候选窗,游戏又不画,结果只剩左上角的系统默认 IME 小框,只能盲打。
对 cs2.exe、dota2.exe 忽略 UI-less,照常由 Server 绘制候选窗。
* fix(server): 前台为 D3D 独占全屏时不弹候选窗与光标状态提示
独占全屏下别的进程的窗口画不上去,弹出去反而可能把游戏踢出独占模式(闪黑、切分辨率、卡死)。
在 UI 线程真正显示前用 SHQueryUserNotificationState 判一次(300ms 缓存),独占全屏就收起候选窗,
并清掉已渲染可见标记,数字键与空格选词不再等待不会到来的绘制。
* fix(engine,server,windows): 游戏自绘候选时后台改动的候选列表实时同步给宿主
英雄联盟等 UI-less 宿主自己画候选。云候选、AI 候选、模型重排、英文混排在按键回复之后才改
候选列表,却从不通知 DLL,游戏还画着上一键读到的旧列表,数字键和空格却按新列表上屏,
于是「选的和上屏的不一样」。
- 契约新增 Worker opcode 35 UiLessCandidatesChanged,载荷与 UiLessComposition 同形,
由 uiless_page.h 统一格式化与解析,并附候选页代号;旧 DLL 读选中位时在第三个制表符处停下,兼容。
- Server 在上述后台改动之后把新页推给候选归属的客户端。
- DLL 收到后回到 TSF 线程核对焦点与组合纪元,更新候选 UI 元素并通知宿主重读。推送与按键回复
走不同管道,按代号只接受不旧于当前的页,避免旧页盖掉新页。
- 从共享内存重读到不同的页时高亮回到第一项,与 Server 每次重建都选中首项一致,
不再保留旧高亮造成「高亮这个、空格上屏那个」。
* feat(windows,server,ui-html,installer): 游戏兼容开关,CS2 / Dota 2 独占全屏打字不再黑屏
CS2、Dota 2 只替内置白名单(按输入法登记名称全等比对)里的输入法处理输入法消息。不在名单里时
组合落到 Windows 默认组合窗 CiceroUIWndFrame,左上角弹出编码小框;独占全屏下这个窗口一出现
游戏就被踢出全屏,表现为一打字就黑屏。清风输入法未开兼容时同样如此。
- 设置页帮助页新增「游戏兼容(CS2 / Dota 2)」:开启后把水杉在系统里登记的名称换成白名单里的
名字(默认「拼音输入法」),游戏会自己画候选。需要管理员权限:设置进程以
--apply-game-compat-name 提权重启自身,写 HKLM 记录值并改语言配置的 Description。
- TSF DLL 注册时以记录值为准,安装/升级重新注册不再把用户选的名称冲掉;卸载时删除记录值。
- 开启时不再对 cs2.exe / dota2.exe 忽略「宿主自己画候选」的声明,避免两个候选框。
- Server 的独占全屏判断覆盖进出独占模式时的 QUNS_BUSY 间隙,不在切换途中弹候选窗。
- TSF 诊断日志在组合开始/结束与 BeginUIElement 时记录宿主窗口状态(只有窗口与标志,没有文本)。
* fix(windows): 后台刷新回调持有加载器引用,宿主卸载 TSF DLL 后不再崩溃
当前输入法是水杉时,CS2 启动途中会加载再卸载 TSF DLL。诊断日志的线程池回调
FlushTsfDiagnosticLogs 正在 Sleep(250),只靠 DllAddRef 撑着:那只回答 DllCanUnloadNow,
挡不住宿主直接卸载。DLL 卸载后 SDL3 映射进同一段地址,回调醒来跑进 SDL3 的代码,
游戏崩溃(0xc0000005,崩溃转储里卸载模块的地址范围与崩溃地址吻合)。
- 诊断日志与统计上报的线程池回调改为用 GetModuleHandleEx 取加载器引用,
回调里 FreeLibraryWhenCallbackReturns,函数完全返回后才放手。
- 析构函数把 DllRelease 挪到最后,不在等待 IPC 线程退出之前就让 DLL 可卸载。
* fix(windows): 游戏自绘候选时不再把 Server 的 HTML 候选页当成候选交给游戏
CS2 开了游戏兼容后打一个码,游戏里的候选只有一项且是乱码。宿主要等 BeginUIElement 才说
自己画候选,而那时组合首键已经不带 UI-less 标记发给了 Server;Server 往共享内存写的是给
自己候选窗用的 HTML 页(辅助码、译文 span),DLL 的候选元素从共享内存回读后整串交给了游戏。
- 开了游戏兼容名称的 cs2.exe / dota2.exe 在 ActivateEx 就认定由游戏画候选,每个按键都带标记。
- 候选会话里收到过 Server 的 UI-less 页之后才从共享内存回读,之前一律不读。
* fix(windows): 游戏自绘候选时翻页能刷新,部分上屏后不再出现乱码候选
三角洲行动(虚幻引擎,以 TF_TMF_UIELEMENTENABLEDONLY 激活)里按 = / - / PageUp / PageDown
翻页,Server 已翻到第 N 页,游戏却还画着第一页;接着按空格上屏的是第 N 页的首项(多为单字),
剩下的拼音继续组合时候选框里出现乱码。
- 翻页、移高亮等键走异步的 WM_AsyncServerCandidateKey,以前把回复当作「只是确认」丢掉;
UI-less 下这份回复就是新的候选页,现在应用并通知宿主重读。
- UI-less 的 _SetText 拿不到 Server 的候选页时不再退回本地引擎的占位列表——那不是候选,
宿主会画成一条乱码。部分上屏后从共享内存回读 Server 写好的新页;_ClearList 同时清掉上次
的页记录,页文本相同也会重新载入。
2026-10-13 21:58:15 +08:00
Hao Qu
e39ea0b11c
feat(server): 添加候选译文词性显示开关 ( #915 )
2026-10-13 21:57:46 +08:00
Lu Fan(SonnyCalcr)
119c439d7a
fix(engine,server): 日文候选不再写进拼音词库,升级回放跳过已残留的日文词 ( #907 )
...
日文 provider 出的候选没有设置 scheme,默认是 Quanpin。在日文模式下选非首选
候选时,Server 按拼音调频,用罗马音作键(pan、amarini)写进拼音日志。msime.db
里没有这些行,UPDATE 改不到任何东西,但 update_pinyin_weight 照样记了日志;
升级回放时 apply_pinyin 找不到行就插入,日文词于是出现在全拼候选里。
- 日文候选标上 SchemeType::JapaneseRomaji
- Server 的选词调频、置顶、造词与云候选落库跳过日文候选
- update_pinyin_weight 没改到行时不写日志
- 回放跳过、打开日志时清掉自动学习来的带假名拼音条目;手动加的词不动
Fixes #869
2026-10-13 12:54:29 +08:00
時崎 ギャラクシー
bcbbdcf74c
Merge pull request #903 from Tokisaki-Galaxy/feat/skin-schema-v2
...
feat(server): 外部皮肤新增 schema_version 2,WebView2 与 D2D 双后端支持九宫格贴图与自由挂件
2026-10-13 00:57:14 +08:00
luo jiyin
d58e706c9c
test(perf): measure per-key model path resolution overhead ( #846 )
...
* test(perf): measure per-key model path resolution overhead
* docs(server): correct model benchmark binary path
* ci(server): upload model path latency sample
* ci(server): repeat model path benchmark three times
* test(perf): measure first-touch missing model paths
* fix(server): isolate model benchmark through CRT environment
* ci(server): measure paths before integration tests
* test(server): isolate model path benchmark from CI
2026-10-12 21:38:16 +08:00
Jia Sui and fanlusky
60c2b26698
fix(engine,server): 全拼纠错收窄「多字」纠错并让开关真正关闭纠错 ( #889 )
...
* fix(engine,server): 全拼多字纠错收窄为仅 QWERTY 邻键插入
多字(插入)纠错只保留「误插 QWERTY 邻键」:生成器 insertion_variants 不再生成重复相邻键(双击),生成式空间不再生成任意字母插入(远键插入)。autocorrect_table.h 随生成器重新生成。
* fix(engine): 全拼纠错开关关闭时真正不再改写切分
纠错开关关掉后真正不纠错:把手误拼写别名层从常开改为跟掩码走(ü 归一 jv->ju / nue->nve 仍常开);两个早于掩码可知的切分入口 QuanpinScheme::build_request 与 QuanpinDictionary::get_or_compute_segments 显式带上掩码,切分缓存键随之隔离。
* fix(engine,server): 纠错开关关闭时辅助码、写回与排序上下文也按字面切分
关掉全拼纠错后,只有方案的 build_request 和查询自身切分不再跑手误别名层,
其余几条路径仍用默认(带别名)的切分,和查询落在不同的键上:
- 辅助码路径自己切底串作为显式切分交给词典,haoyonga 仍被切成 hao'yong'ga;
- 调频、造词、删词、建 SQL、校验去掉分隔符后重切,开关关掉时选中 hao'yong'a
的词会去更新 hao'yong'ga,调频静默失败;
- 排序 / 固定位置的上下文 key(引擎与 server 两处)仍按别名切,laing 与 liang
的固定位置互相串。
改动:
- cut_pinyin_by_mode 的 include_correction_aliases 改为必填,每个调用点显式决定;
双拼词典、设置页词库校验和离线工具传 true,保持原行为。
- 新增 quanpin::correction_aliases_enabled,方案、词典、辅助码与排序 key 共用
(只看换位、邻键两位),修正只带删除 / 插入位的掩码在方案与词典两层判断不一致。
- 词典按最近一次 query 的掩码记录别名开关,写回路径统一走 cut_for_write。
- 会话改为在换方案、改开关时 bind_quanpin_scheme 一次,不再每次 refresh 下发。
- 方案只存 bool;jv -> ju 放回纠错表,去掉合并表。
- 在 CI 实际执行的 test_input_session 中补回归用例(写回、辅助码、固定位置、
方案掩码),每条都确认回退修复后会失败。
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-12 20:41:23 +08:00
Jia Sui and fanlusky
fc90cb1f2c
fix(engine): 纯简拼读法否决权,纠错不再劫持 nbn 等简拼候选 ( #881 )
...
* fix(engine): 纯简拼读法否决权,纠错不再劫持 nbn 等简拼候选
纯简拼形输入(切分全是单字母声母)若词库 jp 列有该输入读法,纠错不得接管:
nbn 是「能不能」、nqn 是「女青年」、bqng 是「并且能够」,纠错却把它们改写成
字母更近的错串候选(难/帮),顶掉真实命中的简拼词。
输入形状分不干净——sahng 也全是合法声母却必须保留乱序纠错;唯一分得开的是
词库有没有这个简拼读法,故判定落在同时持有 DB 与纠错掩码的查询层。
- 新增 quanpin::has_pure_jianpin_reading(jp 列 LIMIT 1 查询)
- QuanpinDictionary::effective_autocorrect_types 统一 query_exact 与
insert_word_to_series_cache 的有效掩码,避免 series 缓存键分歧
- 非纯简拼(shng=[sh,n,g]、shbng、sahng/shangg/sjhang)纠错不变
* fix(engine): 纯简拼整词改为排在纠错前面,不再整个关掉纠错
原方案在词库有纯简拼读法时把纠错掩码置 0,漏了元音的真手误(bng 想打 bang)
也随之纠不了,而且只有词库层知道纠错被关,预编辑与选词消耗仍按原掩码判断。
改为不动掩码:纠错照常进行,纠错分支里字面结果中的纯简拼整词
(literal_jianpin_pinyin_match:两个及以上单字母声母盖住整串,逐个是正读首字母,
a/e/o 不算)和混合简拼一样放进领衔组。纠错读法排在后面,仍可选、仍带纠错标记。
判定直接看已查回的字面结果,不新增 SQL;掩码不变,缓存键也不变,
因此删掉 has_pure_jianpin_reading 与 effective_autocorrect_types。
测试补上预编辑(n'b'n)、选前缀单字只消耗自己的声母、bng 仍保留「帮」。
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-12 17:23:30 +08:00
Lu Fan(SonnyCalcr)
341ca93be5
fix(server): 升级不再关掉老用户的候选词翻译 ( #884 )
2026-10-12 16:47:31 +08:00
時崎 ギャラクシー and fanlusky
add122fcc6
feat: 候选词翻译新增 AI 辅助提供方,收敛为单一 translation.provider ( #876 )
...
* feat(engine): 翻译凭据测试新增 translation.ai 服务类型
* feat(server): 候选词翻译新增 AI 辅助提供方,收敛为单一 translation.provider
* feat(ui-html): 候选词翻译新增 AI 辅助提供方并跟随单一 provider
* fix(server): 将 ai_translation 加入编译目标与测试套件
* fix(server): 在 AiTranslation 命名空间导出 ParseTranslations 供测试调用
* fix(server): 解析模型返回时剥除 Markdown 代码块标记
* fix(server): AI 候选词翻译校验占位 Token、收紧解析,翻译配置改读快照
- AI 翻译的 Token 改用 IsUsableSecret 校验,出厂模板的占位符不再被当成可用凭据
- 解析模型回复时,合法 JSON 但键不对、数组长度不符或残缺 JSON 一律作废,不再把原文当译文显示和写进释义库
- 从旧布尔推导出腾讯云时保留 tencent_tmt.enabled 门禁;在设置页明确选择时才打开,升级不会替用户向腾讯云发送候选词
- 候选词翻译读取的 provider 与各服务配置合成一份加锁快照,配置重载时整份替换,候选线程和翻译 worker 不再直接读会被改写的全局字符串;每个任务只解析当前服务的配置
- provider 与三个旧布尔一次原子写入;旧的 niutrans/custom enabled 开关改为切换 provider
- AI 联想与 AI 翻译共用 ChatCompletions 传输层,翻译超时与 AI 联想一致改为 8 秒
- 设置页凭据测试与运行时共用 AiTranslation::FromConfiguredTranslation,provider 白名单只保留 IsValidTranslationProvider 一处
* fix(ui-html): 候选词翻译的 AI 配置提示随 AI 辅助页实时更新
AI 辅助页改服务商、地址、Token 或模型后,翻译区的提示和摘要立刻刷新,不用重开设置窗口;可用性判断与服务端一致,占位 Token 不算已配置。
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-12 16:47:04 +08:00
fanlusky
797c0f5652
feat(server,ui,ui-html): 候选窗可严格按文字宽度收紧
...
皮肤新增 [candidate_window] fit_content,设置页「外观」新增「候选窗口按文字收紧宽度」
(appearance.candidate_window_fit_content),两者取或。打开后:
- D2D 不再垫 160 DIP 卡片最小宽度和列表 80 DIP 下限,行尾不再多留 6 DIP,
右侧留白与序号左侧留白相同;
- WebView2 去掉 .container 的 7em 下限;
- 同一输入里宽度不再只增不减,高度仍保持。
皮肤的 min_width_dip 与装饰图宽度照常生效;内置皮肤清单出厂为 false。
2026-10-12 02:03:59 +08:00
Lu Fan(SonnyCalcr)
f64da66e6c
fix(server): 混输 emoji 最匹配的一个放首页末位,其余排在所有候选末尾 ( #853 )
...
此前所有混输 emoji 都追加在候选列表末尾,候选一多就全落到最后一页。现在知道每页候选数时,
查询结果里最匹配的那个 emoji 放在首页末位,其余 emoji 仍排在末尾,颜文字照旧紧随其后。
- 补全词的默认位置和学到的英文槽位在有 emoji 时让到首页倒数第二位,两者都留在首页;
用户固定位置的英文仍然优先。
- CurrentEnglishPlacement 在没有英文候选时也带上每页候选数,emoji 才能定位。
- 选中 emoji、颜文字不再算越过英文,不会让英文槽位后退;否则首页末位的 emoji 每选一次
都会把英文往后推。
2026-10-12 01:02:02 +08:00
Lu Fan(SonnyCalcr)
19543ead61
fix(server,installer): 升级不再改掉老用户设置和效果档模型,SimplySign 打包前构建词库 ( #852 )
...
* fix(server): 升级不再把只给新装用户的出厂默认值推给老用户
* fix(installer): 升级时把 0.9.x 随包的效果档模型挪到 models\neural-desktop,不再删掉
* fix(installer): SimplySign 完整包打包前从同级 msime-dictionary 构建词库并备好模型
2026-10-12 00:27:59 +08:00
Lu Fan(SonnyCalcr)
0d7ae4ca79
feat(server): 翻译里的词性与分隔符单独配色 ( #848 )
...
候选翻译(如 "adj. spreading; n. sound of laughter")由 Server 切成单词、词性、
分隔符三段:WebView2 端包成 .cand-pos / .cand-sep,D2D 端经
CandidateList::Item::translationRuns 用分段画刷绘制,两端同一切法。
新增皮肤键 translation_pos / translation_separator 及选中行的
selected_translation_pos / selected_translation_separator,留空时与翻译同色。
内置皮肤的翻译改用 Notion 调色板:词性取相邻的另一个色相并降到 50% 不透明度,
分隔符为单词色 45%;铺实色高亮的选中行另配一组。仓库内的外部皮肤同步补上词性与
分隔符配色。
2026-10-11 23:28:30 +08:00
Lu Fan(SonnyCalcr)
0c754b4a04
fix(server): 辅助码会话用例显式打开辅助码开关 ( #850 )
...
#847 把出厂模板的 shuangpin_helpcode / quanpin_helpcode 改成默认关闭后,
测试辅助码行为的会话用例沿用模板默认值,在辅助码关着的情况下运行,CI 的
Server 测试有 10 个用例失败。
新增 ScopedHelpcodesEnabled,在这些用例里先于会话构造把两个开关打开,结束时
还原。只改内存里的开关、不写配置文件,开发机上跑也不会改动用户配置。
2026-10-11 23:21:02 +08:00
Lu Fan(SonnyCalcr)
715028e1b9
feat(server): AI 联想上下文跳过密码框、换应用清空、过滤类凭证串 ( #845 )
...
AI 联想会把最近的上屏文本作为上下文发到云端,以前不区分输入框,也跨应用累积。
- 密码 / PIN 输入框:TSF 在一段输入的首键上读 InputScope(IS_PASSWORD、IS_NUMERIC_PIN 等),
按键包带上 FanyImePipeFlags::SensitiveField;Server 收到后不发 AI 请求,上屏也不进上下文
- 只在 AI 联想开启时才检测:Server 通过新的 worker opcode AiContextUploadChanged(34)
告诉 TSF 开关状态,关着时按键路径只多一次 atomic load
- 上下文按焦点会话归属:client_id 或 activation_epoch 变了就清空,不再把 A 应用里打的字带进
B 应用的请求
- 发送前去掉像凭证的 ASCII 串:不含空白、长度 >= 8 且混了字母 / 数字 / 符号中两类以上
2026-10-11 21:58:34 +08:00
沐雪清泽 and mushiyuki
93c7b8121d
fix(engine): consume Japanese nn as a single nasal ( #669 )
...
Co-authored-by: mushiyuki <248113054+muxueqingze@users.noreply.github.com >
2026-10-11 20:39:55 +09:00
luo jiyin
950649a3a4
fix(server): include page state in candidate frame deduplication ( #834 )
...
* fix(server): include page state in candidate frame deduplication
* test(server): cover existing candidate frame state
2026-10-11 20:39:46 +09:00
Lu Fan(SonnyCalcr)
331d0012f5
feat(server): config.toml 中的 API 凭证改用 DPAPI 加密存储 ( #840 )
...
翻译、语音、AI 助手的 token / key / secret 以前明文写在 config.toml 里。现在落盘时
用 DPAPI(当前用户范围)加密,存成 "dpapi:<base64>",加载后在内存中还原成明文,
业务代码和设置页的行为都不变。
- 加密统一在 WriteConfiguredValues 里做,所有凭证 setter 自动生效
- 启动时把旧版本留下的明文凭证就地换成密文,用户无需重新填写
- 出厂占位符和空值保持明文,升级时的模板合并仍能识别「未填写」
- 解不开的密文(配置被拷到别的账户或机器)按未填写处理,不会把密文当 token 发出去
- IsCredentialKey 从 ime_config_template.cpp 移到新的 ime_config_credentials.cpp 共用
2026-10-11 18:15:12 +08:00
Lu Fan(SonnyCalcr)
649747f8cd
feat(server): 神经网络整句效果优先模型改为按需下载 ( #838 )
...
效果优先模型(sentence-model-desktop.safetensors,约 25 MB)不再随安装包分发,
改为和八股文模型一样在设置页下载后才能使用。
- engine:SentenceAssociationOptions 新增 neural_desktop_model 路径,留空即模型缺席、
静默不重排;词典不再从资源目录固定加载效果档。load_file 按 UTF-8 打开路径,
数据目录在非 ASCII 用户目录下也能读到模型
- server:新增 settings/neural_model,下载到 <数据目录>\models\neural-desktop\,
下载与导入都按 neural-model/lock.json 的字节数和 SHA256 校验后原子落位;
会话层只在开关打开时解析模型路径
- ui-html:设置页增加下载 / 导入 / 删除 / 浏览器下载,模型未就绪时开关置灰
- installer:不再打包效果档模型;旧版装进数据目录根下的那份在覆盖安装与卸载时清掉
原有配置项 sentence_neural_desktop 保持不变,用户的开关状态升级后保留。
2026-10-11 18:08:33 +08:00
MSIME(MetaSequoia IME)
40d24b7341
Merge pull request #827 from chr331/fix/mixed-pinyin-candidate-priority
...
fix(engine): 保留原样混拼候选优先级
2026-10-11 16:18:56 +08:00
Lu Fan(SonnyCalcr)
f273dccd18
feat(server): AI 联想与语音润色支持设置 DeepSeek 思考强度 ( #821 ) ( #824 )
...
新增 [ai_assistant] thinking 与 [voice_input] polish_thinking,可选 disabled / low / high / max,
默认 disabled 保持原行为。非 disabled 时向 DeepSeek 发送 thinking: enabled 与 reasoning_effort,
其他提供商不受影响。开启思考时 AI 联想超时放宽到 30 秒、max_tokens 提到 8192,润色超时放宽到 30 秒;
AI 联想缓存键纳入思考强度。设置页 AI 辅助与文本润色 API 各加「思考强度」下拉框。
Closes #821
2026-10-11 15:23:46 +08:00
chr331
36ab259c43
fix(engine): 保留原样混拼候选优先级
2026-10-11 13:56:14 +08:00
luo jiyin and fanlusky
66e0a6dc76
fix(server): 保留候选文本中的逗号和私用字符 ( #766 )
...
* fix(server): 保留候选文本中的逗号和私用字符
* fix(server): render candidate frame from one snapshot
* fix(server): use captured preedit for sticky card key
* fix(server): dedup candidate frames by item-aware signature
Candidate text now keeps raw commas, so the comma-joined candidate_string
could make ["a,b","c"] and ["a","b,c"] share one frame signature and drop
a real page change as a duplicate repaint. Length-prefix each item instead.
Also serialize the WebView candidate items with the replace error handler
so an invalid UTF-8 translation gloss cannot throw on the UI thread, and
let CandidateWindowContent own its preedit and page snapshot rather than
referencing caller locals.
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-11 02:08:25 +08:00
fanlusky
f414570505
test(server): anchor input mode lookup to line start in legacy path migration test
2026-10-10 23:14:20 +08:00
fanlusky
90e812fe4e
fix(installer): start fresh installs in Chinese and ship opt-in features off
...
- input.default_ime_mode defaults to chinese, matching the Server and TSF fallbacks
- utility.emoji_mode / kaomoji_mode default off so Shift+E / Shift+M no longer swallow
English words that start with a capital letter
- voice_input, ai_assistant and tencent_tmt default off; without a token they only pop a
prompt (voice on Right Alt, which is also AltGr) or do nothing
- doubao_enable_ddc defaults off, matching its comment and the code fallback
- drop general.enable_emoji, which nothing reads
cloud_candidates stays on: the installer's network page asks the user and only writes
false when unchecked. Code fallbacks in ime_config are aligned with the template.
2026-10-10 23:02:15 +08:00
Lu Fan(SonnyCalcr)
5e03628a7e
feat(installer): build cn-en translations into the local dictionary ( #784 )
...
* fix(server): drop part-of-speech labels from Ctrl+Enter translation senses
The machine-translated Chinese-to-English glosses prefix each sense with a
label ("n. silver medal", "proper n. Wanshan District"). The candidate
window keeps showing the whole gloss, but splitting it for Ctrl+Enter now
strips the label so it never reaches the committed text.
* feat(installer): build cn-en translations into the local dictionary
build-dictionary.py gains a cn-en-translations stage that loads
sources/cn-en/machine-translations.txt from msime-dictionary into
zh_en_glosses verbatim, keeping every sense instead of the two the ECDICT
derivation keeps. It runs after english-glosses and before
custom-translations, so it overrides ECDICT and custom/translations.txt
still overrides it.
Local full test packages now always build the dictionary from the sibling
msime-dictionary checkout instead of downloading the product-lock release:
Invoke-LocalTest.ps1 and prepare-package-inputs.ps1 call
build-dictionary.py --if-stale, which skips only when out/ was built from
the current clean source commit by the current builder. CI and releases
still take the dictionary from product-lock.json.
2026-10-10 21:17:03 +08:00
Ouchihao
777fb2aef4
fix(engine): protect repeated-initial jianpin
2026-10-10 17:05:09 +08:00
Ouchihao
29c8917e8c
fix(engine): preserve leading-initial mixed jianpin
2026-10-10 14:46:13 +08:00
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
AkaneIwasa and fanlusky
568d07f513
feat(windows): 添加中日英三语轮换 ( #717 )
...
* feat(windows): 添加中日英三语轮换
* fix(windows): 三语轮换改为快捷键开关并修复两端状态不同步
- 开关移到「快捷键 → 中英文切换」下的「允许中日英循环切换」,配置键改为
[keybindings] trilingual_cycle;输入模式恢复为中文/日文,二者互不影响
- 循环请求带显式标记位和请求方自身的中英/日文状态,Server 据此计算目标语言;
普通 VK_SHIFT 仍是中英切换,不再被误当成循环
- Server 开关在请求途中被关闭时仍回复,按中英切换处理,TSF 只丢弃后续排队按键,
不再超时重连
- 已发出的循环回复未被应用(含 Superseded)时走完整重连,避免日文状态两端不一致
- 循环切换补上光标处状态提示和标点同步
- 切换语言时复用暂存的另一语言会话,不在按键路径上重建引擎和打开 msime.db
- 配置读取的语言与开关改为原子量;TrilingualCycleChanged 的能力过滤移到发送方
- 中日切换不再重发 TrilingualCycleChanged;结束组合被拒绝时不计入统计
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-09 15:44:41 +08:00
時崎 ギャラクシー
aa5c632ea9
Merge pull request #711 from Tokisaki-Galaxy/feat/llm-model-fetch
...
feat: AI 辅助新增获取模型、测试连接与 Custom 提供商
2026-10-08 23:13:01 +08:00
normaltank
c2bd59d448
fix(server): 翻页扩展时保留混输候选并同步 Emoji 末尾排序
2026-10-08 22:10:13 +08:00
normaltank
6489d4be17
feat(server): 调整 Emoji 混输候选项位置至候选列表末尾
2026-10-08 22:10:13 +08:00
fanlusky
06fb8f87ba
fix(server): 关闭顶字且混输关闭时第五码仍走顶字,避免丢字与两端分叉
...
混输关闭时码表答得出的完整四码保留四码上限,关掉顶字后第五个字母会被 Server
裁掉,而 raw 预编辑样式的 TSF 已经显示了它,两边缓冲就此分叉。顶字开关改为只在
混输开启时生效(字母并入混输串),混输关闭时仍按顶字上屏首选。
同时修正第四键注释(两个开关作用在不同按键上)、设置页与配置模板的说明文字,
以及 settings_app.cpp 新增行的缩进。
2026-10-08 14:10:36 +08:00
Jia Sui
3d31a40a74
feat(server): 五笔四码自动上屏与顶字各加一个设置开关
...
「四码唯一时自动上屏」和「第五码将首选上屏」此前都是无条件行为,用户遇到
误上屏没有任何出口。四家主流五笔(搜狗/QQ/百度/微软)都提供这两个开关且
默认开启,这里补上并保持默认开,升级用户零行为变化。
- input.wubi_four_code_auto_commit(默认 true)门控四码唯一自动上屏
- input.wubi_fifth_code_top_commit(默认 true)门控真顶字
- 开关只落在 Server 判定层,引擎完全不知道:WubiInputOptions 不加字段,
避免测试里大量聚合初始化静默取默认值
- 顶字关闭后第五个字母落回引擎既有四码上限(混输关=裁掉,混输开=并入混输
串),与搜狗 PC 一致,不补新分支
- 顺带修正 input_key_policy.h 与 event_listener_keys.cpp 中把不存在的开关
当既成事实引用的注释,以及两个把「无条件」写进名字的用例
2026-10-08 13:24:25 +08:00
Ehtasham-Yasin
0fe601e259
feat(server): submit converted shuangpin with Shift+Enter
2026-10-06 15:09:29 +02:00
Lu Fan(SonnyCalcr)
5d6eaa5bd1
feat(server): 全拼纠错候选的 * 标记可在设置中关闭 ( #631 )
...
新增 quanpin.autocorrect_marker 开关,默认开启(显示 *),关闭后纠错得到的候选
不再在末尾附加 * 标记。只影响候选窗显示,不影响上屏文字和词频。
同步出厂模板、工作配置、两个设置宿主的读写映射和设置页「输入」分区的开关,
并在配置持久化测试里覆盖默认值、落盘重读和缺键回退。
2026-10-05 22:04:06 +08:00