一把伞南星 and fanlusky
71960b8301
feat(server,ui): 悬浮工具栏图片模式与装饰图叠加候选词 ( #1046 )
...
* feat(server,ui): 悬浮工具栏图片模式与装饰图叠加候选词
在 #1046 的基础上按最新 develop 重做。
悬浮工具栏 [toolbar] mode = "image":一整张背景图,按钮按
[toolbar.buttons.<按钮>] 的 x_dip / y_dip / width_dip / height_dip 摆放,
可按状态换图([images]),没图时画矢量图标。窗口按背景图的透明区域裁成
异形,透明处点得穿;图上除按钮外都能拖动。v2 皮肤的动图会播放,工具栏
隐藏或淡出后停帧。
候选窗装饰图可用 candidate_overlay_* 叠加一个候选词,太宽时缩字号;
设置页的皮肤预览一并显示。
ui 新增 OverlayPanel(绝对定位)与 ImageMask(按 alpha 生成区域)。
* fix(ui): 动图工具栏的窗口形状取所有帧的并集
窗口区域连画面一起裁,只按首帧裁形状时,动画里伸出首帧轮廓的部分
(抬头、飞出的纸)会被裁掉。改为把所有帧的 alpha 合起来再生成区域。
* fix(server): 工具栏按钮框始终算在异形窗口里
窗口形状只取背景图不透明的部分时,摆在图片透明处的按钮会被一起裁掉、
点不到。形状改为背景图轮廓并上每个按钮的框,按钮可以放在人物旁边的空白处,
不必在背景图里垫底。
* feat(server): 工具栏按钮可单独设内置图标的字号
[toolbar.buttons.<按钮>] 新增 icon_size_dip,内置 Segoe Fluent Icons 图标的
字号不再只能跟着按钮框走:按钮框铺满背景图里的圆底、图标单独调大小。
不写时仍是按钮框短边的 0.82 倍。
* feat(server): 设置页按图片模式预览悬浮工具栏
皮肤页的卡片与悬浮工具栏页的预览原来只会画矩形条。皮肤是图片模式时,
改按工具栏的画法预览:背景图(v2 皮肤的动图会播放)、按皮肤坐标摆放的
按钮、按钮贴图或内置图标(含 icon_size_dip),设置页关掉的按钮不画,
缩放与图标尺寸设置一并生效。
---------
Co-authored-by: fanlusky <1730976608@qq.com >
2026-10-20 23:08:01 +08:00
Lu Fan(SonnyCalcr)
e701cebbe4
feat(server,ui,installer): 内置皮肤改由皮肤清单定义,新增微信绿(卷轴)内置皮肤 ( #1061 )
...
* feat(ui): CandidateList 支持等宽网格列与关闭选中态
- Appearance::gridColumns:横排时按可用宽度均分成等宽列(列数不超过 gridColumns,每列不窄于
minItemWidth),放不下一列的项占多列。
- Appearance::selectable:为 false 时不画任何选中态,首项也能正常显示悬停与按下效果。
* feat(server,installer): 内置皮肤改由皮肤清单定义,新增微信绿(卷轴)内置皮肤
内置皮肤数据化:
- skins/default/<id>/skin.toml 从只放开关改为完整的出厂清单(配色、圆角、版式、工具栏、名称与说明),
并新增 canvas 基底的清单。候选窗、悬浮工具栏、光标状态徽标不再在代码里写死任何内置皮肤的参数。
- 出厂清单在构建时编进程序;数据目录里的清单写了的键覆盖出厂值,缺失或写错时退回出厂外观。
安装包改为每次整份覆盖 skins\default。
- 皮肤清单新增版式键(padding、item_gap、number_inset 等,长度可写 DIP 或 "0.3em"),以及
[candidate_window.horizontal] / [candidate_window.vertical] 分排列覆盖、page_arrow_divider、
toolbar.icon_corner_radius_dip。
- test_candidate_skin_tokens 保留改动前的内置分支作参照,逐个皮肤、主题、排列与字号比对清单解析结果。
共用候选窗场景:
- 候选框的场景搭建与套皮肤抽成 CandidateSkinScene,候选窗与设置页的皮肤预览共用;设置页预览改用
真实的候选窗控件绘制,删除原先移植自网页样式的预览绘制与各皮肤硬编码。
卷轴展开(expand_panel)与微信绿(卷轴):
- 皮肤开关 expand_panel / expand_rows:横排候选行右端的展开按钮,展开后首行与后续候选网格一起滚动,
右侧细滚动条;展开与收起只认按钮,展开时滚轮上下滚动、不翻页。
- 网格点选按绝对下标上屏并在工作线程核对显示文字;滚到底部时自动再展开一批候选。
- 新增内置皮肤 wechat_scroll「微信绿(卷轴)」。
2026-10-18 20:42:06 +08:00
Lu Fan(SonnyCalcr)
e9825a521f
feat(server): 优化设置窗口滚动手感并加入启动画面 ( #1045 )
...
* feat(ui): 滚轮平滑滚动贴近浏览器手感
- 每次滚轮的平滑滚动改为 cubic ease-out,接续当前速度,不再有指数逼近的长尾
- 滚动距离跟随系统「一次滚动的行数」,「一次滚动一屏」时按整页滚动
- 合成交换链的帧时间对齐到 DWM 的刷新网格,消除绘制开始时刻抖动带来的位移抖动
* fix(server): 设置页滚动到 Niya Demo 皮肤时不再卡顿
Niya Demo 的 background.png 实际是 1280x720 的 WebP,预览第一次滚入视野时在界面线程同步解码,首次加载 WebP 解码器要 100-200ms。皮肤预览的静态图改为打开页面时就在后台线程解码,界面线程只创建位图。
设置页与词库表格的滚轮步长同时调到 100(与 Chrome 一致),平滑时长 260ms。
* feat(server): 设置窗口加入启动画面与开关
打开设置时先在窗口中央显示齿轮图标(Win11 用 Segoe Fluent Icons U+E713,Win10 回退 Segoe MDL2 Assets),等首个 configSnapshot 填好控件后再淡入主界面,避免输入方案先显示全拼再跳到双拼。齿轮至少停留 200ms,淡出 140ms。
「关于」页新增「启动动画」开关(appearance.settings_launch_animation,默认开启),关闭后只短暂显示纯色背景。新键已写入出厂模板和开发配置,并补了默认值与读写往返测试。
2026-10-18 00:27:50 +08:00
Lu Fan(SonnyCalcr)
a98acfee24
feat: 候选窗支持系统亚克力与云母背景材质 ( #1033 )
...
皮肤在 candidate_window.backdrop 写 acrylic 或 mica 时,候选卡片圆角范围内垫一层系统材质:
acrylic 模糊后面的窗口,mica 模糊桌面壁纸(Windows 11,更早的系统按 acrylic)。材质按
Fluent 配方叠「模糊背景 → 亮度层 → 色调」,色调取 surface,深浅主题各自用
backdrop_opacity / backdrop_luminosity 调色调与亮度层的不透明度。
msimeui 的 DeviceResources 新增 backdrop composition:经 Windows.UI.Composition 把 D2D
画进 CompositionDrawingSurface,与材质的形状在同一次提交里更新,卡片伸缩时边缘不错位;
交换链 Present 与合成提交分属两条路径,实测会错开。没写 backdrop 的皮肤仍走交换链。
有材质时卡片阴影只画在卡片外,ShadowCache 改按 D2D 设备判断缓存是否可用。
系统关闭透明效果或建不起 Windows.UI.Composition 时退回交换链,surface 按不透明画。
附 acrylic-demo、mica-demo 两个样例皮肤。
2026-10-17 16:02:38 +08:00
Lu Fan(SonnyCalcr)
cc868151a8
feat: 新增 canvas 基底,D2D 候选窗支持 v2 九宫格、挂件分层与 APNG/GIF 动图 ( #1014 )
...
* feat(ui): 新增 APNG/GIF 动图解码与动画帧时钟
AnimatedImage 按 APNG 规范解析 acTL/fcTL/fdAT 并校验序号、CRC 与帧边界,逐帧重建 PNG 交给 WIC 解码后按 dispose_op/blend_op 合成;GIF 走 WIC 多帧解码。延时规则与浏览器一致,超限或损坏的动画退回静态首帧。
DeviceResources::GetImageFrame 按动画时钟取帧并汇报下一次换帧时刻,动图帧按 64 MB 预算缓存;Scene 与 Window 据此按需重绘,可整体关闭动画。DrawNineSlice 按 CSS border-image 语义区分源切片与目标边宽、支持 fill,并用夹取画刷消除接缝渗色。
* feat(server): 新增 canvas 基础皮肤并要求 v2 皮肤基于它
canvas 是全贴图基底:透明面板、无描边、无圆角、无阴影,外观来自九宫格面板图与挂件。它只能作为外部皮肤的 base,不进内置皮肤列表;v1 皮肤用它直接报错。
schema_version = 2 而 base 不是 canvas 的皮肤按 v1 加载、忽略全部 v2 字段,并在扫描结果里记一条问题。v2 字段补齐校验:图片限 .png/.apng/.gif/.webp,fill 必须是布尔,偏移与 z_index 有范围,挂件最多 32 层。
* feat(server): D2D 候选窗补齐 v2 九宫格、挂件分层与动图
canvas 皮肤在 D2D 候选窗里按 CSS border-image 语义绘制九宫格面板:切片以源图像素计、边宽以 DIP 计、fill = false 不画中心;有面板图时卡片的底色、描边、圆角与阴影让给贴图。content_insets_dip 从面板外缘量起且不小于边框宽度,line_gap_dip 只作用于预编辑行与候选之间。
挂件拆成卡片前后两层:z_index < 1 在面板之下,其余在面板之上,同层按 z_index 与声明顺序稳定排序;图片在框内等比居中。动图按场景给出的下一次换帧时刻排一次性定时器续帧,只在候选窗显示时运行,隐藏、换皮肤时停;系统关闭动画效果时只显示首帧,v1 皮肤保持静态。
设置页原生预览认得 canvas 基底并绘制面板图。
* feat(examples): 新增基于 canvas 的 v2 全贴图皮肤样例
canvas-demo 用 2 倍九宫格面板、面板下层的叶子挂件和面板上层循环播放的 APNG 星光演示 v2 皮肤,素材均为程序生成的几何图形,随目录以 MIT 授权。样例测试同步校验 schema 2 与 canvas 互为前提、v2 图片扩展名与数值范围。
* docs(examples): 说明 canvas 基底、v2 九宫格与挂件分层及动图规则
schema 说明去掉「仅 WebView2」,写明 v2 必须以 canvas 为 base、canvas 只能当 base;九宫格切片按源图像素、边宽按 DIP,content_insets_dip 不小于边宽,line_gap_dip 只管预编辑行与候选之间;挂件以 z_index 1 为界分在面板上下两层;动图格式、帧时长、上限与系统减少动画时的行为。server/docs/ui-backends.md 与 skins/README.md 同步更新。
* docs(server): 候选窗与皮肤目录的注释不再引用已删除的 WebView2 页面
2026-10-17 02:57:33 +08:00
Lu Fan(SonnyCalcr)
ef28cf690d
fix(server,ui,ui-html): 打磨 Direct2D 设置窗口:图标、检查更新、热力图、滚动与冷启动 ( #1001 )
...
* fix(ui): SVG 按整像素栅格化、滚动改为跟手的指数滑动,并可预热 D3D 设备
- GetSvgBitmap 按四舍五入的像素尺寸建位图,避免 D2D 向上取整后被挤压采样
- ScrollViewer 平滑滚动改为按帧时间逼近目标:连续滚轮不再每格从零速重起,
内容按整设备像素排布,滑动中文字不再抖动
- 新增 DeviceResources::PrewarmComposition,在后台线程提前创建 D3D11 设备,
首帧复用,省去约 200ms 的驱动初始化
* fix(server): 修复 Direct2D 设置窗口的图标、检查更新与热力图交互,加快冷启动
- 侧栏等 SVG 图标对齐设备像素绘制,不再发糊
- 关于页「检查更新」:页面持有状态,点击不再无反应;按钮加悬停描边与按下位移;
后台任务结果改为投递消息回窗口,窗口被遮挡时不再因 WM_TIMER 被压制而卡在「正在检查…」
- 弹窗按显式宽度测量内容,换行文字不再与下一行重叠
- 以 --about 打开时侧栏指示条落在「关于」
- 日历热力图可横向滚动(拖动滑块、点击轨道、Shift+滚轮),滚动条与竖向一致:
8px、无箭头、2px 圆角;悬停格子 500ms 后显示日期与字数
- 滚轮每格 60px;暗色主题首帧前不再闪白(按主题色擦底并在首帧前隐藏窗口)
- 启动时预热 D3D 设备,首帧从约 300ms 降到约 140ms
* fix(ui-html): 热力图滚动条与页面竖向滚动条一致,检查更新按钮加悬停与按下反馈
与 Direct2D 设置窗口的同步改动保持一致。
2026-10-16 18:51:21 +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
時崎 ギャラクシー
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
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)
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
fanlusky
d256385264
perf(ui): 候选文字布局按内容跨帧复用
...
原来每次 Measure 都清空按项缓存的 DirectWrite 布局,每帧为每个候选重建全部
布局。改为按文字、字号与排版框缓存:移动选中、后补的翻译或云候选重绘同一批
字符串时直接命中,下一键的页面也常在别的下标复用上一页的字。字体或外观变化
时整体清空,条目数有上限。
2026-10-05 13:02:46 +08:00
fanlusky
fef743e0b1
perf(ui): 卡片阴影只模糊一次,按九宫格拉伸到任意尺寸
...
阴影缓存按卡片精确尺寸作键,打字时卡片几乎每键都变大小,每帧都要重建两遍
高斯模糊,约占候选帧一半的开销。离四角足够远处模糊后的边缘沿边不变,所以
只为刚好够到这段直边的尺寸模糊一次,绘制时切成九块、拉伸中间的条带;切口
落在直边内部,逐像素平铺无缝。
新增像素对比测试:4 种 DPI、2 种圆角、6 种尺寸下与逐帧完整模糊最大相差
7/255(原缓存为 6/255),切片接缝会差到阴影本身的 alpha。
2026-10-05 13:02:46 +08:00
fanlusky
e2bdeb418b
perf(ui): 位图缓存加 LRU 上限
...
GetBitmapFromFile 的缓存从不淘汰,换过的皮肤图片按原始分辨率解码后一直留到设备
重建。调用方每帧按路径重新取、不持有指针,超出 4 张时丢掉最久未用的即可。
2026-09-30 19:58:18 +08:00
fanlusky
ec00892121
feat(server): 新增仿微软拼音的内置皮肤 microsoft
...
- 候选窗:深色 #2C2C2C 底、#383838 选中底、#E183D9 紫色选中条,序号与候选同字号,
横排每项最小 4.35em、间距 0.28em(换行的行间同样隔 0.28em);尺寸均按字号缩放
- 翻页:默认开启,实心圆角三角,与候选行等高,横排前加分隔线
- 悬浮工具栏沿用默认页面,拖拽条改为紫色
- ui:PagerArrows 新增 Glyph::Triangle 与分隔线,三角用单一路径填充,半透明时不出现描边重叠;
CandidateList 新增 minItemWidth 与 selectedBarInside
- 设置页新增皮肤卡片与预览;更新内置皮肤列表、文档与配置注释,补充测试
2026-09-30 17:35:38 +08:00
fanlusky
806a4b1977
feat(ui): 新增 PagerArrows 翻页箭头控件
...
两个用线条绘制的「上一页 / 下一页」小按钮,不依赖字体;支持置灰、悬停与按下态,
按钮贴在槽位右下角,并提供 GlyphWidth 供调用方对齐箭头。
2026-09-30 12:42:14 +08:00
fanlusky
19bd5deae0
feat(ui): 候选列表支持行底内边距与横排行铺满
...
contentPadBottom:换到第二行的翻译和辅助码从行底内边距上方开始排,内边距挪到最后一行下面,行高不变。
justifyHorizontalRows:横排时把列表多出的宽度均分给同一行各项,末项贴着列表右边。
2026-09-30 01:33:47 +08:00
fanlusky
07c9dea9f9
feat(ui): 候选选中行翻译色与 TextBlock 背景、底部分隔线
...
CandidateList::Appearance 新增 rowTranslationSelected,选中行的翻译可以单独配色。TextBlock 新增 SetBackground 和 SetBottomRule,底部分隔线计入测量高度;高度折叠到分隔线以内时两者都不绘制。
2026-09-29 21:57:23 +08:00
fanlusky
0f627ef41d
feat(ui): Card 支持按圆角裁剪的背景图
...
Card::SetBackgroundImage 在底色之上、边框和子元素之下绘制图片,支持 Fill / Uniform / UniformToFill 与不透明度。ImageStretch 从 Controls.h 移到 Layout.h,供 Card 和 Image 共用。
2026-09-28 19:36:37 +08:00
fanlusky
7bbb9042fc
perf(ui): 缓存卡片阴影、TextBlock 字体格式和候选列表文字度量
...
- Card:每帧为每道阴影新建离屏位图、画刷和高斯模糊特效。改为把全部阴影
合成到一张位图,按尺寸、圆角、DPI、阴影参数和 render target 复用;
尺寸不变的重绘(选中项移动、译文与云候选补齐)直接贴图。合成失败时仍
走原来的逐帧绘制。
- TextBlock:每次测量都新建 IDWriteTextFormat,自定义回退字体还要把系统
回退表整份复制进新 builder。格式与文字、光标无关,改为只在字体、字号、
对齐或回退字体变化时重建。
- CandidateList:一帧里会测量多次(自然尺寸、保留尺寸、按最终宽度排版),
每次都为每段文字新建 DirectWrite layout,一页九项每键约一两百个。文字
宽高只取决于文字、字号、宽度和字体,改为记忆化,字体或外观变化时清空,
超过上限整体重来。空的辅助码和译文不再创建 layout。
2026-09-27 15:03:16 +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
0b4d9172f8
feat(ui): CandidateList 让贴着列表四角的项使用外框圆角
...
Appearance 新增 outerCornerRadius 与 outerTopCornersEnabled:选中或悬停的
填充里,真正落在列表四角上的角改用外框半径,其余角保持 cornerRadius。
既支持内缩高亮与外框同 R,也支持整行铺满、只在外框四角处贴合的皮肤。
2026-09-26 21:49:04 +08:00
fanlusky
a54e2e08e8
fix(ui): 候选窗高亮行的辅助码与翻译跟随选中文字色
...
微信绿皮肤下高亮行的辅助码压在 #07C160 绿底上仍是暗色,与 webview 不一致。
候选行绘制里 rowTextSelected/rowLabelSelected 只覆盖候选文字和序号,辅助码
(annotation)和翻译一直无条件使用 appearance_.annotationColor。而皮肤 CSS 里
这两者是 .text 的子节点(.cand-content / .cand-translation),颜色继承自 .text,
选中行的 `.first .text { color: ... }` 会一并覆盖它们——D2D 端分开绘制,这层继承
关系就丢了。
改为在高亮行显式跟随 rowTextSelected,翻译再乘 CSS 的 opacity .62 保持原有观感。
判据是 rowTextSelected 的 alpha,所以各皮肤自动与各自 CSS 对齐:wechat 与
willow_green 白色,graphite #111827/#f1f3f5,fluent 没有 .first .text 覆盖,
沿用普通文字色不变。
2026-09-14 14:45:11 +08:00
Jia Sui
3dea733f64
fix(ui,server): 候选窗 D2D 阴影按皮肤对齐 webview——Card 支持 pass 列表
...
D2D 候选窗的 Card 阴影是内置 Win11 漫射三层(σ11/6/2.8,α0.42/0.30/0.48):
四边对称、无偏移,紧贴边缘合成 α≈0.49、暗晕铺到 15~20 DIP。webview 端候选窗
皮肤 CSS 用的是带右下偏移的双层软阴影(light: 8px 10px 24px rgba(0,0,0,.18)
+ 2px 3px 8px rgba(0,0,0,.10))。用户实机截图剖面实测:webview 底边峰值 α≈0.16、
D2D 0.41,差 2.5 倍,即「D2D 阴影偏重」的根因。对称三层无论怎么调参都拟合不了
带偏移的衰减曲线;浮动工具栏已有的 SetShadowScale 只缩模糊半径压不了深度
(高斯在边缘恒贡献 α/2)。
给 Card 拆出数据驱动的阴影 API,阴影参数跟皮肤走(与颜色/圆角同模式):
- ui/include/msimeui/Layout.h、ui/src/Layout.cpp:ShadowPass{σ,α,offset} +
SetShadowPasses(空列表保持内置 Mist 三层,逐位不变)、SetShadowEnabled
(整体开关,语义对齐 Popup 同名 API)、SetShadowOpacity(uniform 缩 α,与
SetShadowScale 正交);渲染统一走 DrawGaussianShadowPass,无 device context
时兜底 DrawLayeredMistShadow
- server/src/window/candidate_presenter.cpp:ApplySkin 按皮肤设阴影——内置四皮肤
与自定义包用皮肤 CSS 标准对(σ=blur÷2)light {12,0.18,(8,10)}+{4,0.10,(2,3)}、
dark α .34/.22;默认皮肤 webview 端 body HTML 无 box-shadow,D2D 同步关掉
- 浮动工具栏(scale=0.45)与托盘菜单(全默认)不触新 API,观感不变
- 透明垫余量重验:新 pass 可见范围(α>0.02 阈值)左16/上14/右32/下34 DIP,
均在左32/上20/右32/下40 垫内,无裁切切痕
2026-09-14 12:34:10 +08:00
fanlusky
ee5b50133f
fix(ui): 竖排候选窗选中项高亮铺满整行
...
d2d 渲染下,竖排候选窗被卡片最小宽度撑大时,候选项的自然宽度小于卡片内宽,
选中高亮与命中区域只覆盖到文字宽度,右侧留下大片空白(候选项较长、宽度超过
卡片最小宽度时表现正常)。
根因:候选项行矩形取自按自然宽度测量得到的 itemGeometry。列表虽被拉伸到卡片
内宽,但绘制前 Present 阶段会以窗口宽度重新测量,把每项宽度还原为自然宽度,而
此时排布命中缓存(矩形未变)被跳过,铺满逻辑无法重新生效。
改为在 ItemRect 中直接以列表最终布局宽度 bounds_ 计算竖排行矩形,不再依赖逐项
自然宽度,绘制与命中同时受益,且不受测量/排布缓存影响。右侧留白由卡片内边距
提供,与左侧保持一致。横排路径不变。
新增 GetItemBounds 访问器与三个回归测试,其中一个复刻了 Present 重新测量的时序,
可捕获此前方案的退化。
2026-09-14 02:04:58 +08:00
古明四季
42bfd9fc49
fix(ui): 修复候选列表溢出与换行后的点击区域
2026-09-11 23:34:57 +08:00
Jia Sui
62b4688aa1
feat(ui): DeviceResources 与 Window 支持渲染 DPI 覆写
2026-09-11 22:21:57 +08:00
Jia Sui
bd7cf1114d
fix(server): D2D 内置皮肤补齐 light 配色,对齐 WebView2 CSS
...
Signed-off-by: Jia Sui <jsfaint@gmail.com >
2026-09-11 22:19:24 +08:00
Aegon8719
dea9292814
issue-55 候选窗支持可配置的有序回落字体
2026-09-09 18:03:56 +08:00
fanlusky
43555460db
fix(server): fall back to text when the icon font lacks the glyph
...
The floating toolbar and the emoji panel hardcoded "Segoe Fluent Icons",
which ships with Windows 11 only. DirectWrite substitutes a font silently
instead of failing, so on Windows 10 every private-use codepoint the toolbar
draws (U+E982, U+F110, U+F138, ...) rendered as a blank box: the buttons
still worked but no longer showed any state.
Resolve the font per codepoint rather than per family, because "Segoe MDL2
Assets" is a subset of Segoe Fluent Icons and swapping the family alone would
still draw tofu wherever a glyph is missing:
- add msimeui::ResolveIconGlyph(), which probes the installed icon fonts with
IDWriteFont::HasCharacter() and returns the first family that really carries
the glyph, or no family at all;
- give every toolbar and tab icon a text label to fall back on (中/英, 半/全,
简/繁, ...) when neither font has the glyph;
- drop the unused ToolbarIconButton::SetGlyph/SetLabel, which would bypass the
resolved family.
Add unit tests for the resolver, covering the missing-glyph path that cannot
be reached on a host that has Segoe Fluent Icons installed.
2026-09-08 12:41:01 +08:00
Evan
42238a2af6
style: 用 .clang-format 重排 server / windows / ui / log
...
一次性重排,无任何行为改动。四个目录各自的 .clang-format 放在仓库里已久,但全组织只有
MSIME-Linux 在 CI 里执行 clang-format 检查,这边 149 个文件里有 149 个不符合自己声明的风格。
已逐文件核对语义等价:去掉空白、注释与相邻字符串字面量拆分之后,全部 149 个文件与重排前逐字节
相同。差异只有三类——缩进与换行、clang-format 补的 } // namespace 结尾注释、以及长字符串被拆成
相邻字面量(C++ 保证自动拼接)。
这个提交会写进 .git-blame-ignore-revs。
2026-09-06 12:13:47 +09:00
fanlusky
a0c4daa9ad
Allow Card window shadows to scale for compact surfaces
...
Add Card::SetShadowScale so the Win11 mist shadow can shrink with the
control. The floating toolbar can then keep the same shadow style without
clipping or a oversized host.
2026-09-02 19:12:01 +08:00
fanlusky
2ac86ea0e2
Stop mapping all Unicode through CJK fonts and cut D2D working-set growth
...
Custom font fallback no longer covers the whole BMP/SIP, so Segoe UI Emoji
can paint color glyphs again; CJK still prefers Noto Sans SC then YaHei.
Drop GaussianBlur compatible targets during BeginDraw (they retained GPU
memory as the candidate window grew), grow the composition swapchain in
64px steps without shrinking, and reuse Card chrome plus cached text
formats instead of reallocating them every layout.
2026-09-02 16:25:54 +08:00
fanlusky
5421c1dd1b
Add SVG icon rendering, toggle switch, and font fallback for MenuFlyoutItem
...
MenuFlyoutItem gains leading SVG icons (ID2D1SvgDocument), an optional
trailing toggle switch, and content-based width measurement so tray-style
menu items match the HTML menu layout. Default UI font is now Noto Sans SC
with Microsoft YaHei fallback via IDWriteFontFallback; CreateTextFormat
gracefully falls back when the primary family is missing.
2026-09-02 16:03:57 +08:00
fanlusky
d16f9f3fea
Add DirectComposition hosting and candidate-list chrome for the IME window
...
Adopt an existing HWND, render through D3D11/DXGI/DirectComposition, and
extend CandidateList with horizontal layout, skin colors, click-to-commit,
and a D2D context menu. Preedit TextBlock draws a caret in a fixed insert
slot so neighboring glyphs reflow instead of using letter-spacing; the
default end caret sits slightly after the last character.
2026-09-02 15:29:14 +08:00
fanlusky
64c08a7c02
Adjust some controls for emoji panel.
2026-08-15 02:32:00 +08:00
fanlusky
f3c7a9557a
Set the initial position setting method for the window.
2026-07-20 23:22:05 +08:00
fanlusky
548330b8cf
Make a demo of an on-screen keyboard.
2026-07-15 18:22:50 +08:00
fanlusky
3a41372f24
Adjust font size and some layouts
2026-07-15 15:50:50 +08:00
fanlusky
59a73b8476
Optimize the emoji panel size.
2026-07-15 15:43:58 +08:00
fanlusky
05a4ada19d
Optimize the emoji panel.
2026-07-15 15:34:53 +08:00
fanlusky
604cf987b1
emoji panel demo step01
2026-07-15 14:49:36 +08:00
fanlusky
4f62123699
Support image render
2026-07-15 14:39:55 +08:00
fanlusky
e210c8eb4c
Allow popups to scroll out of view
2026-06-19 13:00:35 +08:00
fanlusky
d2ca118d89
Add candidate hover highlight
2026-06-19 11:52:43 +08:00
fanlusky
33350ab7c2
Trim candidate header text metrics
2026-06-19 11:34:30 +08:00
fanlusky
718d4f9559
Align candidate preview typography
2026-06-19 11:06:54 +08:00
fanlusky
41f4571bd2
Add candidate popup keyboard navigation
2026-06-17 20:20:17 +08:00
fanlusky
10cfb70d66
Add candidate popup preview primitives
2026-06-17 19:08:27 +08:00
fanlusky
e1156b32e2
Highlight scrollbar on hover
2026-06-17 16:44:51 +08:00
fanlusky
3aa1a650a6
Add centered text alignment for TextBlock
2026-06-16 18:28:50 +08:00