Commit Graph
143 Commits
Author SHA1 Message Date
Lu Fan(SonnyCalcr) 5aed0fcbf0 fix: 修复部分用户打不开设置页,WebView2 缺失时仍可正常打字 (#801)
* fix(installer): VC++ 运行库要求提到 14.40 并给出直接下载链接

服务端程序用 MSVC 14.40+ 编译并导入 msvcp140.dll,配上更旧的运行库,
std::mutex 首次加锁即访问冲突、进程无声闪退,设置页因此打不开;原先
14.20 的门槛放过了装着 2019 / 早期 2022 运行库的机器。

- 缺失与「已装但过旧」分开提示,并显示当前版本
- 「是」直接下载 VC++ x64 运行库与 WebView2 Evergreen Bootstrapper
- 更正 WebView2 缺失的影响:只有设置页需要它,默认 D2D 候选窗照常打字

* fix(server): WebView2 不可用时设置页给出提示,候选窗退回 D2D

- 设置进程不再忽略 WebView2 environment / controller 创建失败(运行时缺失
  时同步失败、回调不来,界面会一直停在启动画面),改为弹框说明原因、错误码
  与下载直链后退出
- ui_backend = webview2 而检测不到运行时时,本次进程改用 D2D 渲染,保证能
  正常打字;不改配置,装好运行时后下次启动自动恢复
- WebView2 下载地址统一为 Evergreen Bootstrapper 直链
2026-10-11 02:21:40 +08:00
AkaneIwasaandfanlusky 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
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
Lu Fan(SonnyCalcr) 5d6eaa5bd1 feat(server): 全拼纠错候选的 * 标记可在设置中关闭 (#631)
新增 quanpin.autocorrect_marker 开关,默认开启(显示 *),关闭后纠错得到的候选
不再在末尾附加 * 标记。只影响候选窗显示,不影响上屏文字和词频。

同步出厂模板、工作配置、两个设置宿主的读写映射和设置页「输入」分区的开关,
并在配置持久化测试里覆盖默认值、落盘重读和缺键回退。
2026-10-05 22:04:06 +08:00
Lu Fan(SonnyCalcr) 53ee180ec3 feat(engine): 直接辅助码句中四码可用第二位辅码大写结束 (#630)
直接辅助码的四码在句中原来只能补 / 结束(uiab/),现在也可以把第二位辅码敲成大写(uiaB)。
设置页「直接辅助码句中四码标记」两个勾选框可多选、至少留一个,默认只勾 /。

- 引擎:拼写图新增 Aux2Upper(非缩写)。开着大写标记时大写字母只能当第二位辅码,
  走不通再退回不分大小写的旧规则,第一位辅码敲大写(uiAuiQ)照常可用。/ 的收键受勾选控制。
- 协议:DirectHelpcodeChanged 载荷改为 "0"/"1"/"2"(2 = 开着但 / 不是编码键),
  TSF 据此决定吃不吃 /。
- 配置:新增 helpcode.shuangpin_direct_helpcode_slash / _uppercase,同步写入出厂模板、
  工作配置和两个设置宿主的读写映射。
2026-10-05 20:43:02 +08:00
Lu Fan(SonnyCalcr) 3c79876205 Merge pull request #629 from fanlusky/feat/v-mode
feat: 新增 V 模式,数字转中文与算式计算
2026-10-05 17:51:21 +08:00
Lu Fan(SonnyCalcr) 5208753ce8 feat: 句中辅助码新增大写字母触发方式 (#620)
* feat(engine): add uppercase trigger for shuangpin mid-sentence helpcode

With the uppercase trigger on, an uppercase letter right after a complete
two-key syllable opens a mid-sentence helpcode block by itself, as if the
backtick had been typed before it: ulpbXihfa is ulpb`xihfa, and a following
uppercase letter is still the second code (ulpbXYih is ulpb`xYih). The raw
input keeps the typed letters; the block rules live in
contracts/mid_sentence_helpcode.h so TSF, Server and engine parse alike,
including the semicolon final, which no longer counts uppercase blocks.

The scheme now hands the parsed layout (source index and decorations) to the
request, so selection advance and preedit no longer re-parse the raw input.
Adds the MidSentenceHelpcodeUppercaseChanged worker opcode (31).

* feat(windows): count uppercase helpcode blocks before backtick and semicolon

With MidSentenceHelpcodeUppercaseChanged on, TSF uses the shared block rules
when deciding whether '`' opens a block and whether ';' is the ing final, in
both the synchronous and the deferred key classification.

* feat(server): wire the mid-sentence helpcode uppercase trigger

New helpcode.shuangpin_mid_sentence_helpcode_uppercase (default off) in both
config templates, both settings hosts and the settings page as a third
trigger checkbox. It takes effect only with mid-sentence helpcode on and
direct helpcode off; the Server applies it to the semicolon final rule and
broadcasts MidSentenceHelpcodeUppercaseChanged to TSF.
2026-10-04 21:00:41 +08:00
Lu Fan(SonnyCalcr) 22fb1e2569 Merge pull request #619 from fanlusky/feat/shuangpin-direct-helpcode
feat: 双拼直接辅助码(万象式,无需引导键)
2026-10-04 19:32:10 +08:00
HowGeGe 5e77dffabf fix(server): preserve endpoint and model per provider (#605) 2026-10-03 23:18:41 +08:00
fanlusky af34e23d07 feat(server): 语法模型支持浏览器下载与本地导入,新增网络代理设置
应用内下载 octagram 模型较慢时,设置页每个模型行提供「浏览器下载」直链,
下载后用「导入」选中 .gram 文件:后台复制进模型目录,与应用内下载走同一套
格式校验与原子落位,原文件不动。导入与下载共用单槽。

帮助页新增网络代理(跟随系统 / 直连 / 自定义 HTTP 代理),新增 [network]
配置段。云输入、模型下载、AI 联想、翻译、语音识别与润色、凭证测试统一经
NetworkProxy 选择代理,改动即时生效。WinHTTP 的「跟随系统」由 DEFAULT_PROXY
改为 AUTOMATIC_PROXY,真正读取用户的系统代理与 PAC。

契约新增 collocationModelImport 消息;旧设置宿主补上 openExternalUrl。
2026-10-03 22:49:07 +08:00
fanlusky 05d202ce5b feat(server): 日期时间候选支持调频、置顶、固定位置,并加「📅日期」格式入口
日期时间候选(Shift+T 模式与 rq / sj / xq 混输)按格式 ID 调频:日期文本每天都变,
所以给每种格式一个稳定 ID,学到的顺序记在用户库新表 date_time_format_order,固定位置
借用 fixed_candidate_positions。T 模式与混输共用一份顺序,混输取排第一的格式。右键
置顶、固定位置、取消固定对日期候选生效。

混输时在第三位放一个「📅日期」入口(时间为「🕒时间」),选中后不上屏,候选框整页换成
全部格式,与 Ctrl+Enter 译文页同一套子页机制。新增开关 utility.date_time_menu,默认
打开,出厂模板、工作配置、两个设置宿主与设置页同步更新。UILess 宿主不显示入口。
2026-10-03 20:44:22 +08:00
fanlusky 233ac9ef33 feat(engine,server,windows,ui-html,installer): 句中辅助码触发键可多选,新增分号
设置页「句中辅助码触发键」可勾选反引号和分号,至少保留一个。

- 分号只在 AcceptsMarkerAt 成立(这一节是偶数键)时才当触发键;微软/搜狗/紫光双拼的
  ing 韵母只跟在奇数键之后,两者不抢同一个位置,判断时分号先让给 ing 韵母
- 无论按哪个键,TSF 按键缓冲、Server raw 与引擎输入串里都记成反引号,引擎解析不变
- 新配置项 helpcode.shuangpin_mid_sentence_helpcode_backtick / _semicolon 同步写入出厂
  模板、工作配置与两个设置宿主
- opcode 28 保持「反引号是否触发」、载荷单个 "0"/"1"(TSF 会丢弃更长的帧);分号走新增
  的 opcode 29,旧 DLL 忽略它
2026-10-02 23:55:46 +08:00
Jia Sui 03c0a4246d feat(server,ui-html,engine,installer): 接入社区多 octagram 模型,分模型下载与单选激活 2026-10-02 20:15:40 +08:00
Jia Sui 8f22f68d4c refactor(server,ui-html): 万象模型撤下未评测说明与hash检查
有效性判定收敛为单一标准:能被引擎读取端打开(格式锁)即已下载——
「未经评测」的前提随上游更新不再成立,摘要比对、旁挂 .sha256 与
reviewed 字段不再有任何用途,全链路移除:

- collocation_model:删 kReviewedSha256、Sha256Hex(含 bcrypt 依赖)、
  DigestSidecar/ReadRecordedDigest;NOTICE.md 保留 CC-BY-4.0 署名四要素
  (来源/许可/文件名/字节数),删 SHA256 行与重训备注
- 双宿主快照序列化对称删 reviewed;设置页 ready 文案固定「模型已就绪」,
  删「上游已更新,未经评测」分支
- 顺删本文件从未使用的 <sstream>/<atomic>

行为变化:老用户数据目录里的 .sha256 旁挂文件不再被读取,按整个 models
目录的保留逻辑留到卸载才消失,无害。

验证:clang-format 18.1.8 --Werror、Server 双宿主 Release 构建、
pnpm test 91 例、tsc/vite build、全仓 grep 无残留。
2026-10-02 20:15:40 +08:00
Jia Sui 98f7d61284 refactor(server): 万象合并为单个总开关
sentence_collocation_additive + sentence_collocation_rerank 两个键、两个 UI 开关合并为
sentence_collocation_enabled + 一个「万象语法整句」。上游 RIME-LMDG 只有单开关形态
(__include: octagram + grammar/language),它公布的句子正确率 +15%(61.71% → 76.86%)
对应的正是解码期接入,没有「只开重排」的评测;两个开关对同一份模型是可分性的过度承诺。

顺带清掉一个死开关:引擎的 SentenceAssociationOptions 里根本没有 additive 字段,
加成分由 collocation_model 非空隐含开启。GetConfiguredAssocSentenceCollocationAdditive
的唯一消费者是设置页回显,写入的值没有任何读取方——这是「开关开了没反应」的第二处
断点,与模型 id 那处叠加。现在契约对齐:开关关则连路径都不解析,模型缺席则重排一并关闭。

保留 sentence_collocation_model(手动换模型包的逃生口)与两个权重(高级调参,本就
不进设置页)。

行为变化:MergeConfigIntoTemplate 以模板为骨架重建用户配置,模板里没有的键会被丢弃,
因此旧的两个键消失、新的 sentence_collocation_enabled 取模板默认 false,等于已开启的
用户被重置为关闭。可接受——该特性此前因模型 id 从未被写入而根本无法生效,不存在可被
重置掉的行为。

改动面 14 个文件:配置层四处、会话接线一处、双宿主序列化与 configUpdate 分发各两处、
两份 config 模板、设置页四处加测试。

验证:全仓旧键零残留,clang-format 18.1.8 --Werror 通过,Server/Settings 构建 exit 0,
pnpm test 91 例通过,tsc 通过。
2026-10-02 20:15:40 +08:00
Jia Sui e1a664a194 fix(server): 万象下载器改用格式锁,撤下无依据的评测宣称
锁定值与上游实际资产不符(字节数 409719852 vs 409412652,摘要 ae43724a… vs 873cbbb3…),下载在字节锁处失败。上游 LTS 会被原地重传且无不可变资产 URL,摘要硬锁意味着每次重训都要改代码发签名安装包,否则全用户下载失败,这个成本消不掉。

改为锁格式:删字节数常量,总长取响应 Content-Length 并在收完后比对一次(截断检测);新增 ValidateFormat 让引擎读取端自己开一次(魔数 + 双数组边界,不按文件自带长度做堆分配)。摘要不再参与放行,只判断 reviewed 并写入旁挂 .sha256(状态查询要频繁调用,不能每次重算 400MB 哈希)。真实上游字节按 open() 判据复核精确贴边通过:array_size=102353152,收尾正好在 409412652。

kReviewedSha256 保留旧值,摘要不符即 reviewed=false,设置页明示「上游已更新,未经评测」,NOTICE 记录实际摘要与字节数并附差异说明。契约无需重生成:sentence_collocation_model_status 是两个宿主各自拼的 ad-hoc JSON,不在 schema.json 内。

撤下无法验证的宣称:设置页删掉「评测 top1 +6 个百分点」(仓里没有评测工具、没有 docs/research,该数字无法复现),改为描述机制;清掉两处对从未进仓的文档与工具的引用(docs/research、tests/src/gram_reader、eval_lm_compare);修正 octagram_gram.h 里被本次改动失效的「摘要校验在下载侧做」。配置只改注释、未增删键,五件套映射不适用。
2026-10-02 20:15:39 +08:00
Jia Sui 69092b9d9a feat(server): 万象模型的配置链路、模型包解析与按需下载
- [association] 新增五键:sentence_collocation_additive/rerank(设置页开关,默认
  关)、sentence_collocation_model(模型包 id,下载器写回)、两个权重(配置文件
  高级项,不进设置页);出厂模板与工作配置同步更新,通过五件套映射下发
- 模型包确定性布局 <DataDir>/models/<id>/<id>.gram,解析只是一次 stat;开关开
  着但文件缺席即视为关闭,词格静默降级
- collocation_model.{h,cpp}:WinHTTP 按需下载(重定向放行、进度回报)+ BCrypt
  SHA256 校验 + 同卷原子落位 + CC-BY-4.0 NOTICE。SHA256/字节数在常量里钉死:
  上游 LTS release 会被原地重传,换字节必须显式更新并复跑离线评测
- CandidateSource::Collocation 落库/学习判定与神经整句同类,候选徽标〔万象〕
- 下载器编译进 Server 与独立设置进程两个宿主,状态以磁盘为准
2026-10-02 20:15:39 +08:00
fanlusky 79b0bf3aaa feat(server,ui-html,installer): 回车上屏英文入库加开关
设置页「输入」新增「回车上屏英文时入库」开关,对应 input.enter_learns_english_word,默认开启保持原有行为。关闭后回车仍上屏英文,但不再写入英文词库。
2026-10-02 18:45:08 +08:00
fanlusky 45c473158a feat(engine,server,windows,ui-html): 双拼预编辑可显示转换后的全拼
外观里行内预编辑与候选窗预编辑各加一个「双拼显示转换后的全拼」开关,默认关闭。
开启后在双拼方案下:行内原始按键显示不带分词符号的全拼,拼音分词显示带分词符号的
全拼;候选窗显示带分词符号的全拼。

- 引擎新增 get_shuangpin_preedit_forms,同时给出原串切分与全拼切分,不受
  shuangpin_preedit_mode 影响。
- 原始按键样式下 TSF 不等 Server 回包,开关开启且为双拼时 Server 下发的实际样式
  改为 pinyin,回包里再按用户样式去掉分词符号;换方案时重新下发。
- 转换后字母数与按键不再对应,Server 在预编辑末尾附光标映射表
  (engine/contracts/preedit_caret_map.h),DLL 用它定位光标和处理方向键,
  无表或长度不符时回落到原有字母映射。
2026-10-02 16:14:50 +08:00
fanlusky 3a7adb6f1a feat(server): 日期时间混入候选,混输查询合并到同一条线程
- 新增 MixedCandidates(src/mixed/):英文、emoji、颜文字、日期时间共用一条后台线程,
  按一次输入查完、一次回调交回任务线程合并,候选窗每个按键最多因混输刷新一次。
  删除 EmojiIme / KaomojiIme;EnglishIme 只保留英文状态、Shift+Y 和候选译文
- 日期时间混入候选:全拼 / 双拼下整串是 rq / riqi / date、sj / shijian / time、
  xq / xingqi / week(双拼按方案换算后的整拼也算)时,首个格式排在首个中文候选之后、
  云 / 英文 / emoji 之前,其余追加在末尾;选中直接上屏,不调频、不能固定或删除
- 新增 utility.mixed_candidates(候选混输总开关,默认开)与 utility.date_time_candidates
  (默认关);总开关关掉后英文、emoji、颜文字、快捷短语、日期时间都不混入,各自的值保留。
  两份配置模板与两个设置宿主同步读写
2026-10-02 03:39:23 +08:00
fanlusky fae80660c1 feat(engine,server,windows,ui-html): 双拼句中辅助码
在完整音节后敲反引号,接着的字母筛这个音节上的字:第一码大小写均可,
紧跟的大写字母是第二码,之后可以接着打,一个输入里可以有多段。开关
helpcode.shuangpin_mid_sentence_helpcode 默认关闭。

约束在整句解码时生效,而不是解完再筛:
- Google 解码器在 add_char_qwerty 里送 extend_mtrx_nd 之前按约束过滤词条,
  锁住的字带着上下文重新整句解码;约束变化时整段重解,不污染增量搜索。
- kenlm 词格建图时按约束筛边,受约束的跨度不截断地查词库;神经重排只在
  词格 n-best 里挑,自动满足约束。
- 普通词条、云和 AI 候选按同一规则收尾校验;满足不了就不出整句。

反引号段在请求里换成手动分隔符,原串留给宿主回读与预编辑显示;选词推进
时剩余音节上的约束随原串保留。输入形状规则放在 contracts/mid_sentence_helpcode.h,
TSF、Server、引擎共用,新增 Worker opcode MidSentenceHelpcodeChanged = 28。
googlepinyinime-rev 已与上游解绑,AGENTS 与 UPSTREAM.md 同步说明。
2026-10-02 02:20:37 +08:00
fanlusky dde06afd7f feat(server): 候选框显示翻页箭头并接入设置页预览
- D2D:横排在候选右侧多一窄列,竖排在最后一行下方、「‹」与序号左对齐;开关或排列方式变化时重建场景
- WebView2:页面按 data-page-arrows 显示箭头,点击经 candidatePage 翻页
- 箭头点击走 WM_PAGE_CANDIDATE_ARROW,不受鼠标滚轮翻页开关影响;页面快照带上一页 / 下一页可用状态
- 两个设置窗口宿主下发内置皮肤的 page_arrows,外部皮肤条目带解析后的 pageArrows
- 安装包把 skins/default 以 onlyifdoesntexist 放到数据目录,升级不覆盖用户改过的清单
2026-09-30 12:42:25 +08:00
fanlusky 7ad6a42f12 feat(server): 外部皮肤新增细分配色、菜单、外框线宽、高亮圆角、阴影与字体族 2026-09-29 22:08:00 +08:00
fanlusky 2415da274f feat(server): 候选中混排快捷短语并参与调频
- 全拼 / 双拼(非五笔、无辅助码、非造词)编码精确匹配时,把快捷短语组放到固定位置候选
  之后,翻页扩展时重新放置;Shift+K 模式不变
- 新增 utility.quick_phrase_candidates(混入候选)和 utility.quick_phrase_frequency
  (参与调频),默认都开,utility.quick_phrase 仍只管 Shift+K;两份配置模板与两个设置宿主
  同步读写
- 选中快捷短语或越过它选普通候选时异步写入槽位,K 模式里的选择不学;英文最高权重提升
  忽略快捷短语
2026-09-29 14:31:51 +08:00
fanlusky c9b86e0026 feat(engine): 支持用户自定义双拼方案
用户在数据目录 shuangpin\custom\ 下放 TOML 文件,在设置页以 custom/<文件名>
选用。零声母规则从 o、a、first_letter、full_pinyin 四种里选,声母和韵母
映射由文件指定,可用 [zero_initials] 覆盖个别零声母音节。

- 引擎:新增 CustomShuangpinLayout 与 BuildCustomShuangpinProfile,校验缺键、
  声母撞键,并对全部音节做往返解码,冲突时给出可读的错误信息;新增运行时
  方案注册表,按需加载。
- Server:扫描并解析自定义方案,配置快照带上方案列表与目录;文件缺失或无效
  时回退到小鹤。
- 设置页:仿照自定义辅助码,新增打开目录和刷新按钮;无效方案列出但禁用,
  悬停时显示错误。
- 安装器:覆盖安装与迁移数据目录时保留 shuangpin 目录。
- 文档:docs/custom-shuangpin.example.toml 提供带详细注释的示例。
2026-09-29 11:33:23 +08:00
fanlusky 995174af47 feat(server): 造词时 Esc 可只清除未选拼音、保留已选词
新增 input.escape_keeps_selected_word(默认 false)。开启后,造词中按 Esc
只清掉还没选的拼音,保留已选的词,候选窗只显示该词作为 preedit;
再按一次 Esc 整体取消(小狼毫风格)。R 模式下仍整体取消。

- server:HandleCreatingWordEscape 以 CompositionRestored 帧回复
- windows:_HandleEscapeCancel 读取回复并应用,超时或不支持时回退到原取消
- ui-html:设置页「输入」增加开关
- 配置模板、两个设置宿主同步新增该键
2026-09-29 01:58:38 +08:00
Lu Fan(SonnyCalcr) 97049ffd7c Merge pull request #517 from metasequoiaime/refactor/wubi-pinyin-mixed-input
feat(engine,server,ui-html,installer): 五笔拼音混输改为同时混排并拆出独立开关
2026-09-29 00:37:40 +08:00
fanlusky 0b4a3d374a feat(server): 外部皮肤用 skin.toml 的 [toolbar] 表配置悬浮工具栏,替代 toolbar.css
toolbar_stylesheet 只注入 WebView2 页面,D2D 工具栏完全看不到,两个渲染器的工具栏配色因此不一致。
改为在 skin.toml 里用 [toolbar] corner_radius_dip 与 [toolbar.dark]/[toolbar.light] 的
background、border、handle、divider、icon、hover 声明覆盖:D2D 在基础皮肤之上叠加这些值,
WebView2 由 Server 生成当前主题的 CSS。颜色只放行颜色值会用到的字符,避免跳出 CSS 声明。

toolbar_stylesheet 随之移除,不做兼容:外部皮肤里的 toolbar.css 不再生效。
2026-09-28 20:07:30 +08:00
fanlusky facafdcd7b refactor(server): 移除外部皮肤 manifest 中已无用途的 preview 字段
preview 原本只用来充当候选框装饰图;装饰图改由 decoration.image 指定后,它不再被任何渲染或设置页使用。
2026-09-28 19:51:51 +08:00
fanlusky 24b2444a3d feat(server): 外部皮肤支持候选框背景图、自定义圆角与装饰图对齐
- skin.toml 新增 candidate_window.corner_radius_dip、candidate_window.background(image / fit / opacity)和 decoration.image / decoration.align
- decoration 表改为可选;存在时 image、top_inset_dip、width_dip 必填且图片必须存在,不再回退到 preview
- D2D 候选框的装饰图与卡片同列排布,按 width_dip × top_inset_dip 等比缩放、贴在卡片上方且不重叠,卡片最小宽度遵守 min_width_dip 和装饰宽度,与 WebView2 渲染一致
- WebView2 端生成对应的背景、圆角和对齐 CSS;皮肤重载后 D2D 场景随之重建
2026-09-28 19:36:37 +08:00
Jia Sui 456fdb819c feat(engine,server,ui-html,installer): 五笔拼音混输改为同时混排并拆出独立开关
Signed-off-by: Jia Sui <jsfaint@gmail.com>
2026-09-28 17:55:36 +08:00
fanlusky 841b846f64 feat(server): 整句候选来源标签可在设置页关闭
新增 association.sentence_source_badge(默认开启,保持现有行为),
控制候选窗整句候选后的〔Trigram〕〔Unigram〕〔神经D〕〔神经K〕标签是否显示。
关闭只隐藏标签,不影响候选内容与排序;云/AI 角标不受影响。

同步更新出厂模板、开发配置、两个设置窗口宿主的读写映射和设置页开关。
2026-09-28 12:04:43 +08:00
fanlusky 4e17d27ea7 feat(server,ui-html,installer): 悬浮工具栏支持无交互自动隐藏
新增 general.floating_toolbar_auto_hide(默认关闭)和
general.floating_toolbar_auto_hide_delay(1–60 秒,默认 5)。开启后,工具栏显示满延时且
无交互时约 0.4 秒淡出并隐藏;鼠标悬停在工具栏上时倒计时重置,淡出中移入会立即恢复。
中英、全半角、标点、Caps Lock、英文模式、简繁或日文模式真正变化时重新显示并重新计时;
普通的焦点切换和 IME 激活不会把已自动隐藏的工具栏带回来。

悬停用 GetCursorPos 与 GetWindowRect 轮询判断,两者同为物理像素,不涉及 DPI 换算,
也不需要页面侧新增消息,D2D 与 WebView2 两种后端共用。预热、首帧宽限和 cloak 期间不计时。
淡出结束时以 alpha 0 隐藏,下次显示之前再恢复 255,避免在隐藏瞬间闪出一帧不透明画面。

两个新键已写入出厂模板和开发配置,两个设置宿主的字段列表与分发都已补上,并放在
general.floating_toolbar_ 按钮项前缀兜底之前。设置页在工具栏卡片内新增开关和缩进的
延时行,延时用新增的通用 −/+ 步进器,开关关闭时延时行置灰。
2026-09-28 01:09:10 +08:00
fanlusky 0a1b302b1c feat(server,ui-html,installer): 设置窗口后台驻留默认改为关闭后立即退出
settings_window_linger 的出厂默认值从 "10m" 改为 "off"。出厂模板、开发配置、
缺键/非法值回退、设置进程初始值和设置页下拉框初始文字一并改;该功能尚未发版,
不涉及老用户配置迁移。

Prepare-PackageFiles.ps1 增加断言:出厂模板的驻留值不是 off 时打包失败。
2026-09-27 23:02:34 +08:00
fanlusky 7d66b2556c feat(server,ui,ui-html): 候选翻译文本支持在皮肤中单独配色
外部皮肤 skin.toml 的 [candidate.dark] / [candidate.light] 新增 translation 键。
不写时沿用候选文字色叠 62% 不透明度;写了就按原值绘制(含选中行)。
D2D(CandidateList::Appearance::translationColor)、WebView2 注入 CSS
和设置页外部皮肤预览三处一致;预览顺带补上此前漏掉的 number 配色。
2026-09-26 23:38:37 +08:00
fanlusky c539d0cf2a feat(server,ui-html): 设置窗口驻留时长可配置,驻留期间降低内存占用
- 关闭设置窗口后隐藏驻留时,把 WebView2 内存目标设为 LOW 并 TrySuspend 冻结页面;
  重新打开时恢复 NORMAL、Resume 后再显示。本机驻留 60 秒后整棵进程树的工作集
  由约 408 MB 降到约 62 MB,重开仍是瞬间恢复。
- 新增配置项 appearance.settings_window_linger,可选 off / 1m / 5m / 10m / 30m /
  60m / forever,默认 10m。off 表示关闭即退出,forever 表示一直驻留。
- 同步出厂模板、开发配置、ime_config 读写校验和两个设置宿主的快照字段与写入分发;
  设置页“外观 → 界面渲染”新增“设置窗口后台驻留”下拉框。
- 新增测试覆盖模板默认值、缺键、非法值、setter 拒绝和逐值往返。
2026-09-26 22:57:18 +08:00
fanlusky 14815e2f43 perf(server,ui-html): 设置窗口冷启动从约 2.6 秒缩短到约 0.7 秒
- 设置页虚拟主机名改为 imesettings.example / candidate-skins.example:
  不带点的单标签主机名会先走一轮网络名称解析,导航后要空等约 2 秒才开始加载。
- 写 WebView2 用户数据目录和配置目录的 ACL 前先检查:已有 Users 完全控制(可继承)
  和 Medium 标签时跳过 SetNamedSecurityInfoW,避免每次启动都把 ACE 传播到整棵缓存树
  (本机约 120 ms 降到 1.5 ms)。
- 先显示窗口和 splash,再准备 WebView2。
- 显示前最多等 150 ms 取得配置里的主题,浅色主题不再先闪一下深色。
- 新增 METASEQUOIA_IME_SETTINGS_TRACE=1 冷启动打点,写入
  %TEMP%\metasequoia-settings-startup.log。
2026-09-26 22:57:18 +08:00
Lu Fan(SonnyCalcr) 4375d80414 feat: 支持导入自定义辅助码,内置“加加”更名为“拼音加加” (#477)
* feat(engine): 支持 helpcodes/custom 下的自定义辅助码

custom 目录里的每个 .txt 都是一套方案,方案名为 custom/<文件名>。
文件开头的 "# name:" / "# name_en:" 注释给出中英文显示名,缺省用文件名;
兼容 BOM、CRLF 和全角冒号。方案名不能跳出 custom 目录。

* feat(engine): WebView 契约新增 openHelpcodeDirectory

设置页请求打开自定义辅助码目录,仅允许 settings 页发送。同步 ui-html/webview2/shared。

* feat(server): 设置页列出自定义辅助码并可打开其目录

配置快照带上 helpcode.custom_schemas 与 helpcode.custom_directory,每次都会重新扫描;
方案文件被删除或改名后回退到 lantian。两个设置宿主都会处理 openHelpcodeDirectory。

* feat(ui-html): 辅助码设置显示拼音加加与自定义方案

内置方案“加加”改名为“拼音加加”。自定义方案追加在内置方案之后;新增说明区,
提供“打开目录”和“刷新方案”两个按钮,刷新完成后弹出提示。

* feat(installer): 升级与迁移数据目录时保留自定义辅助码

升级清理时只清掉 helpcodes 里的内置表,保留 custom 子目录;更换数据目录时一并迁移;
安装时建出 helpcodes\custom。
2026-09-26 20:21:55 +08:00
fanlusky b3b3b3303c feat(windows): 焦点切换到另一个输入框时提示当前中英文状态
新增开关 general.caret_state_indicator_on_focus(默认关闭,需同时开启光标
状态提示)。

- DLL 把以下情况视为“换了输入框”:焦点窗口变化(Win32 编辑框、对话框、
  其他应用各有自己的窗口);焦点经过一段没有可编辑文档的间隙后落到可
  编辑文档上(Chromium、WPF 等单窗口宿主在字段之间就是先失焦再聚焦);
  焦点会话真正结束后重新开始。Chromium 打字时在两个可编辑文档之间直接
  替换文档管理器,不会触发。从 Win+. 面板返回不计入;线程焦点在真正的
  应用切换后返回计入。一次切换的多次回调由定时器合并为一次提示;组字
  过程中、以及没有光标的控件都保持静默。每次判断在 TSF 诊断日志里记录
  判定标志,不含任何文本
- 协议复用 IMESwitch:wch 改为 FanyImeCaretStateTrigger(UserToggle /
  CapsLockEdge / FocusEntered),CapsLockEdge 保持首发时的 VK_CAPITAL
  取值,Server 对未知值按 UserToggle 处理
- Server 在开关打开时显示当前的有效模式(Caps Lock 开启时为“英”);
  配置项同步写入两份模板和两个设置窗口宿主的读写映射
- 设置页在光标状态提示卡片中增加“切换输入框时提示”开关
2026-09-26 17:09:34 +08:00
fanlusky dc7cfa0354 Merge branch 'develop' into feat/issue-229-ime-status-indicator 2026-09-26 13:58:03 +08:00
Lu Fan(SonnyCalcr) 2755c77192 Merge pull request #466 from fanlusky/feat/neural-sentence-association
feat: 神经网络整句联想与多来源整句开关
2026-09-24 14:53:55 +08:00
Jia Sui eac9fa72b5 feat(server): 固定排位候选词显示可配置的徽标
固定排位徽标此前硬编码为 📌,嫌吵的用户既关不掉也换不了。
新增两个配置项:candidate_fixed_badge 总开关与 candidate_fixed_badge_style 样式枚举(paperclip/pushpin/dot),设置页外观分组提供开关与下拉,改动后立即刷新候选页。
配置存枚举名而非字面 emoji,TOML 与日志里不出现图形字符;展示层白名单与配置层同宽,手改 TOML 写错只会退成无徽标。默认样式改为 📎,比实心红钉安静。
2026-09-24 14:32:10 +08:00
fanlusky 16877cb2d0 feat(server): 整句联想来源开关接入配置与设置页
新增 [association] 段的五个开关(词格、Google、神经 desktop / keyboard、去重补位),
同步写入出厂模板、工作配置和两个设置窗口宿主的读写映射,设置页输入分区加对应选项。
2026-09-24 14:03:43 +08:00
AaGMix 902989abc4 feat(server): 显示光标输入状态提示 2026-09-22 23:52:28 +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 bc37ac9a9e feat(installer): 安装时可自定义数据目录位置
词库、用户配置和皮肤此前固定在 %LOCALAPPDATA%\metasequoiaime,整包几百 MB
全压在 C 盘。安装向导新增一页,允许把这部分数据放到任意盘。

程序本体仍固定装在 Program Files:MetasequoiaImeServer.exe 带 uiAccess=true,
只有在受信任目录里这个标志才生效。

运行期的权威来源是 HKLM\Software\Metasequoia\MetasequoiaIME 的 DataDir。
Server、TSF DLL 和引擎三个组件各自按同一顺序解析:METASEQUOIA_IME_DATA_DIR
环境变量 -> 该注册表值 -> %LOCALAPPDATA%\metasequoiaime。三处各持一份实现,
因为组件边界规则禁止 windows/ 与 server/ 互相 include。32 位 TSF DLL 用
KEY_WOW64_64KEY 读,避开 WOW64 重定向。

安全相关的两个约束:

- 安装器在数据目录里写 .metasequoiaime-data 标记。覆盖安装的清理和卸载的整目录
  删除只在看到这个标记(或目录就是历史默认位置)时才执行——用户可能把数据目录
  指到一个本来就有自己文件的文件夹。
- 选择页与 /DATADIR= 走同一套校验:拒绝相对路径、盘符根目录、不存在的盘、程序
  目录内部,以及 Windows/Program Files/各 AppData/用户主目录本身。

升级时改了位置,PrepareToInstall 在停掉输入法进程后用 robocopy /MOVE 搬运用户
拥有的数据(msime_user.db 及其 WAL/SHM/journal、config.toml、config.base.toml、
skins\),词库和前端资源由本次安装重新写入。跨卷移动目录 MoveFile 会失败,所以用
robocopy。用户词库搬运失败会中止安装:否则新版本对着空的 msime_user.db 启动,
ssPostInstall 的回放只记一句 skipped,用户的自造词就静悄悄没了。

测试侧新增 METASEQUOIA_IME_CONFIG_DIR,只改 config.toml 的位置而不搬词库。原先
靠重定向 LOCALAPPDATA 做隔离的办法在装了正式版的机器上已不再成立——注册表值
的优先级高于它。
2026-09-17 22:49:19 +08:00
Jia Sui d4a0796400 feat(windows): 重构智能标点
原「智能标点」是小狼毫 digit_separators 的语义:字母或数字后的 , . : 直出英文,
2 秒内再按同一标点转回中文——后半段靠 SendInput 往应用里补一个 Backspace 再打
字符,落点全靠光标当时在哪。这次换掉主路径:输入中文标点后按空格,用 TSF 编辑
会话就地把它改写成对应英文(。,!?;:、 → . , ! ? ; : /),2 秒内再按同一标点
键撤回中文;原来的直出降为子开关,整个家族默认全关、改为显式开启。

- 按键与会话:转换/撤回是本地文档改写,不进 IPC、不进延迟队列;判据落在
  _IsKeyEaten,OnTestKeyDown 的预判与 _DispatchKeyDown 的第二遍预判共用同一份,
  声称吃掉的键不交还宿主。改写走编辑会话,请求不上时另起一个最小会话把键本身
  的字符写回去,避免已吃掉的键静默丢失。
- 状态:原来散落的九个成员收成一个 SmartPunctuationAction(None / ChineseCommitted
  / AsciiConverted),带焦点令牌、前台窗口和 beforeChar 指纹;清理以分类结果为准,
  丢焦点与上下文栈变化一并清掉。
- 转换范围:。,!?;:、 与单独出现的 “”‘’【】《》() 都是映射表里的单字符
  条目,路径完全一致;成对补全产生的一对(autoClosedPair)不 arm,按空格只落空格,
  不会留下 <》 这类孤儿。
- 开关:总开关 + 中文标点后按空格转换 + 同键转回中文 + 数字后直出 + 字母后直出,
  五键全部默认关;直出拆成数字/字母两个独立子开关(IPC 24 收窄为数字、25 追加为
  字母),TSF 按前字符类型分别查键。
- 命名:子开关「独立符号」改名「中文标点后按空格转换」,配置键
  smart_punctuation_standalone → smart_punctuation_space_convert,IPC 22 只改常量名
  (SmartPunctuationSpaceConvertChanged),编号与语义不变、新旧测试包互通;设置页
  文案同步重写,五处配置链路与死宿主一并跟改。
- 兼容:旧键未出厂、不迁移(升级合并按模板缺键丢弃、取默认 false);编号 23 随
  「按空格整体转换一对」的设计退役并留空不复用。
- 验证:TSF x86/x64 与 Server Release 编译、Server 335 单测、windows_ipc_contract
  x64/x86、设置页 build + 27 测试、clang-format 18.1.8 全绿。真机未跑。

Signed-off-by: Jia Sui <jsfaint@gmail.com>
2026-09-17 09:29:57 +08:00
fanlusky 529060a359 feat(settings): API Key 配置项增加连通性测试按钮
设置页中所有需要用户自填 API Key 的配置项(AI 助手、候选词翻译、
语音识别、语音润色)旁增加「测试配置」按钮,点击后用当前填写的凭据
向服务发一个最小请求,即时反馈配置是否有效。

- server: 新增 ApiCredentialTest::Run 统一分发(chat 发 1-token 请求、
  ASR 传静音 WAV、翻译发单词校验、豆包走 DoubaoAsrClient::TestCredentials),
  settings 可执行文件补上 curl/zlib/bcrypt/winhttp 及 cloud/voice 源。
- engine/contracts: 新增 apiCredentialTest / apiCredentialTestResult 消息,
  已 generate.py 重新生成并 sync-contracts 同步至 ui-html/shared。
- ui-html: credential-test 模块负责发消息与渲染结果;测试按钮改小两号;
  外观页补充字体下拉框加宽至 1.5 倍、加号按钮宽度减半。
- docs(agents): 补充格式化会卡 CI 的注意事项——clang-format 须为 18.1.8,
  且 format.sh 在 Windows 上因 venv 布局失效,需直接调 clang-format 自查。
2026-09-13 22:11:09 +08:00