Repository navigation
Releases
v3.17.0 — 扫描壁纸页重做、鼠标光晕、预设配置
v3.17.0
本次更新集中在设置体验与可读性。
新增
- 扫描壁纸页(右侧边栏版):当前目录 + 扫描/重新扫描 + 正方形缩略图网格(列数自适应)。点缩略图选中,详情区常驻显示名称、容器内实际文件与类型;未选中时各项显示「无」、按钮置灰;选中项带描边与上提阴影,应用后保持。
- 鼠标光晕:外观 tab 第 2 项开关,指针所在面板内部泛出柔光;关闭后零监听、零变量写入。
- 预设配置:常用组合存为预设并一键切换;「保存配置」写回该预设快照,「恢复默认」还原到快照;「+」新建以当前配置为初值;编辑态每个预设右上角出现灰色 × 可直接删除。
- 设置面板随面板宽度自适应,宽屏下不再留白边。
修复
- 代码块横幅(sticky 标题条)不再被标题栏样式规则接管,滚动与吸附全程保持不透明。
- 弹层 / 菜单 / 提示气泡统一到正确层级,气泡不再被容器裁切。
- 「分辨率上限」显示有效值:≥4K 源自动降到 1080p 后,界面同步显示实际生效值(落盘契约不变)。
- 侧栏收起时不再叠加悬浮外壳,修复偶发的界面整体横向位移;另加横向位移自动拉回兜底。
说明
- 无新增依赖;
README.md/README.en.md已同步更新。
v3.16.6 — DSH 0.2.0-rc.2 表面适配(第五批真机)
dsh-mpkg-wallpaper v3.16.6
面向 DSH 0.2.0-rc.2 的宿主表面适配(第五批真机反馈,环境内 Firefox/Android Via 双端取证)。
全部改动都有真机读数支撑,判据 门禁 12/12 全绿。
修复
- 模型/推理选择器里的"直角白矩形"
真机读数:宿主 material 菜单的外壳与 material 内层都是 16px 圆角,而内层滚动容器
._7KE1Ra_groups[role="menu"]是 radius 0,且被我们两条弹层规则(新弹层规则 + 老 G 块)命中
⇒ 它把身后的 58% 白底在方形区域内又糊一遍。修法:打标走突变快路(渲染前生效),
对这类容器用内联!important中和(作者内联 important 高于任何样式表 important,
绕开该规则:is()里 23 个:not()造成的超高特异性)。 - 有壁纸时「+」触发候选菜单 / 子智能体会话树丢模糊(无壁纸时正常)
机制:有壁纸时我们自己的玻璃表面成为 backdrop root,弹层 blur 只能采样祖先内部。
修法:新增专用去截断趟(只加不删,不参与 A/B/C 分类,避免弄坏输入框卡片那条路),
并对子代理树只补模糊、不补底。 - 会话统计 / Token 用量弹框内层"纯白"
宿主dl.bRhRbq_details自身无背景 ⇒ 白是我们在已 80% 霜化的面板里又叠一层 80%(合成 96%)。
修法:内层从霜化名单摘除。 - 右栏收纳态残留 1px 描边 + "内容先收、模糊后收"
修法:停靠件整棵子树opacity:0(不绘制 ⇒ 描边与玻璃一并消失),标记与收纳同一批次写入。 - 空标题栏被我们画出细条(新会话/加载中)
修法:findHostHeader统一广播data-mpw-hdr-blank,空态摘磨砂层;兜底网特异性翻倍。
兼容性
- 保留并通过:目标条
nLMEza_bar、Token 用量 / 会话统计面板的宿主白底(M3/M5/M8 断言钉住)。 better-sidebar0.24.1 重新对锚(_terminalWrap已在该版本消失,意图由_pane覆盖)。
校验
bash tools/check.sh:PASS 12 / FAIL 0(12 步真跑,峰值内存约 1.47 GB)tools/integrity-check.mjs:73/0 通过(文件齐全、元数据、白名单、无凭据/个人路径)- npm 包:
npm pack16 文件 / 998.9 kB,files白名单内(docs/、tools/均不入包);
另在干净目录实测npm install <tarball>→added 4 packages,无报错 - npm:
dsh-mpkg-wallpaper@3.16.6
3.16.4 —— scene 内嵌视频判定改为「只判不取」+ 压缩条目解码加固
3.16.4 —— scene 内嵌视频判定改为「只判不取」+ 压缩条目解码加固
背景读数(本机实测,同一份语料)
/custom-scene-video-check 与 /library-scene-video-check 是客户端在卡片/清单阶段问"这张场景有没有内嵌视频"的路由(lib/client.js 只读响应里的 d.has)。改前这两条路由直接调 ensureSceneVideo() —— 判定与提取一体,会把整段内嵌视频读进内存并落盘:
| 容器 | 大小 | 改前(全量扫描) | 改后(verdict) |
|---|---|---|---|
wallpaperE/小鸟游星野/小鸟游星野_01.mpkg |
792.0 MB | 791.6 MB / 446 ms | 64 KB / 0.4 ms |
wallpaperE/终末地/zmd_01.mpkg |
713.2 MB | 712.7 MB / 635 ms | 64 KB / 1.0 ms |
wallpaperE/白洲梓/白洲梓_01.mpkg |
527.0 MB | 526.4 MB / 441 ms | 64 KB / 1.3 ms |
1004/-爱伦坡.mpkg(视频类) |
73.4 MB | 73.2 MB / 83 ms | 64 KB / 3.6 ms |
改法
- 新增
probeSceneVideoVerdict()(lib/pkg-extract.js):只读 PKG 目录表(readPkgIndexFromFile:64KB 起步、不够按 ×4 倍增到 8MB)+ 候选条目前缀(判定函数与既有快路径共用probeTexVideoDecision),返回{has, decided}。decided:false的三种情形(≥2 条独立视频、TEX 前缀判unknown、松散目录)一律回退ensureSceneVideo(),答案与改前逐项一致,只是回到慢路径。 probeSceneVideo路由先试 verdict(lib/index.js):能判定就直接答{ ok:true, has },不再为"问一句"付整段载荷;两条 check 路由共用这一个 handler。- 新增
decodeStoredEntry():把"是否 LZ4 链"的判定交给唯一口径probeCompressedEntry(与parsePkg同一个函数),原始长度取链头 u64(不信任头解析出来的size,它是存储长度)。修掉"索引先行的头解析条目flags恒为 0 ⇒ 压缩条目被当 raw 用 ⇒ 该路径静默判成没有视频"的构造性缺陷。本机语料 205 个容器里压缩条目 0 个 ⇒ 对现存语料没有观感差异;判据用自造夹具钉住(手搓合法 LZ4 RLE 链,并前置 128KB padding 把它挤出索引头,否则变异体会退化成 no-op)。
判据与读数
tools/scene-video-verdict-test.mjs(挂tools/check.shstep 8,不新增步骤号):15 通过 / 0 失败。覆盖:单条独立视频"只判不取"(读量 < 载荷 1/8);两条独立视频 ⇒decided:false且慢路径仍给唯一答案;无视频 ⇒has:false, decided:true;压缩条目两条路径都必须还原原始字节;结构棘轮(路由先试 verdict、条目读取必须走decodeStoredEntry);可选语料段(缺语料 SKIP)。变异自证:去掉压缩判定 ⇒ 该条必红(实测拿到的长度 36 vs 期望 4096)。tools/scene-video-verdict-audit.mjs(新工具,只读语料):205 个容器 / 19.1 GB,两条路径逐条对拍"是否有视频 + 选中哪条 + 提取字节 sha256" ⇒ 判定不一致 0(含视频 154 个)。- 全量门禁
bash tools/check.sh --full:12/12 PASS。 - 文档:
docs/SCENE-VIDEO-VERDICT.md(口径、读数、未验证边界与复现命令)。
未验证边界(诚实清单)
- 松散目录(
scene.json+ 平铺.tex)一律decided:false回退 —— 未为它单独实现 verdict 分支; - 小型包可能因 TEX 前缀判
unknown而回退(安全方向:答案不变、只是慢); - verdict 读量随 TEX 条目数线性(实测最坏一例 3.45 MB / 47 条前缀),仍远小于整包且与视频载荷无关;
serveSceneVideo(取字节)未改,仍走ensureSceneVideo。
3.16.3
3.16.3
弹层玻璃与提示气泡的同类根因修复(都属于「我们的层/标记与宿主 DOM 的往返」)。
弹层模糊回归
- 现象:指令菜单 / 权限 / 上下文占用只剩一层白色半透明,模糊没了。
- 根因:上一版把「根级模糊层」挪进输入框卡片子树 ⇒ 层的 backdrop root 被卡片
backdrop-filter: blur(14px)截断,采样到的只是卡片内部已经糊过的底色;挂到body又会在层叠次序上压住整个弹层(弹层在卡片的层叠上下文里)。 - 修法:去截断 + 补霜 —— 弹层开着期间摘掉截断祖先的
backdrop-filter(弹层自己的 blur 立刻采样整页,连被它压住的目标条一起糊),并在容器内垫一层inset:0 / z-index:-1、沿用原 blur 的霜层,容器磨砂一点没少。旧的「根级模糊层」机制整体删除(含滚动/缩放重贴、层账本、包含块偏移校正)。
提示气泡底色闪烁 + 白字看不清
- 根因:两个自激环 —— 分类硬前提只认 computed blur(C 类规则把表面的 backdrop-filter 撤成
none⇒ 打标/撤标逐帧),以及兜底底标记重读我们自己画的那层底色。 - 修法:分类放行「已带标记」的表面;已被去截断的祖先照样算截断祖先;标记把当初的理由写进属性值并只走结构性复核;
role="tooltip"一律不接管底色(宿主深底浅字)。
会话里左栏收起掉帧
- 快路里不再夹带
mpwSideLiftSync,prun里三趟全文档扫描改为 150ms 节流 + 180ms 尾随 + 动画期间让路。 - 实测(会话视图):插件每批突变 0.2–0.3ms;删掉全部
:has()规则无差(p95 17.5 vs 17.4)⇒ 排除「CSS 样式重算」;详见docs/ANIMATION-PERF.md§6。
其它
- C 类实底改用自有 token
--mpw-pop-trunc-surface(原来借--dsw-specific-sidebar-fill,在侧栏作用域里被算成透明 ⇒ 面板整个透明)。
判据:popover-glass 25/0(含两条变异自证)、fog-model 96/0、anim-guard 19/0、panel-smoke 5/5、source-heal-token 10/0、style-scope 0 RED/0 REVIEW;全量门禁 PASS 12 / FAIL 0。
3.16.1 — 弹层玻璃改根级模糊层:输入框的磨砂不再被顶掉
3.16.1
修一条由上一版修复引入的回归:为让弹层能糊到页面背后,上一版把包装容器(输入框卡片)自己的 backdrop-filter 摘掉了 —— 结果是"弹层有模糊了,但输入框的模糊没了"。两条都要,所以改做法。
现在的三分类(宿主元素一个都不碰)
| 情况 | 判据 | 做法 |
|---|---|---|
| A 祖先里没有模糊(挂在 body 下的模型/推理选择器) | 无模糊祖先 | 我们自己的 58% 表面 + 自己的 blur(原样) |
B 祖先是已知包装容器(_card/composer/overlayAnchor/_seat/_stack) |
如输入框卡片 | 弹层打 data-mpw-pop-glass,在根级(body 下)垫一层按弹层矩形对齐的模糊层(backdrop root = 整页 ⇒ 真能糊到页面背后);包装容器的磨砂保留;滚动/缩放时重贴 |
| C 其它带模糊的祖先(面板本体,例如子代理展开框) | 在弹层表面集合里 | 什么都不摘,弹层改 88% 实底(糊不到背后就不假装是玻璃) |
顺带修掉根级层的泄漏:弹层被 React 卸载后旧清理逻辑已经查不到它,会在页面上累积隐形 fixed 层;现在按"层自己的账"清理(surface 断开 / 标记摘掉 ⇒ 撤层)。
真机读数(部署档 3.16.1)
- 弹层
data-mpw-pop-glass就位,表面bg = 宿主色 58%; - 包装卡
uV2eYG_card的backdrop-filter = blur(14px)保住了(本版修复的目标); - 根级模糊层的矩形与弹层逐像素对齐(
[623,249,952,320]vs 菜单[623,249,952,320]),backdrop-filter = blur(11px)。
判据
新 tools/popover-glass-test.mjs 14/0(A 静态接线 / B 三条路行为 + 关闭清理 + 硬前提 / C 变异自证"去掉表面模糊前提 ⇒ B7 必红"),取代 popover-untrunc-test.mjs(已删,门禁登记同步);panel-smoke 5/5、fog-model 96/0、anim-guard 19/0、source-heal-token 10/0、style-scope 0 RED / 0 REVIEW;全量门禁 PASS 12 / FAIL 0(第一次跑到第 2 步出现过一次"0 行"的瞬时假红,同树复跑 12/12 全绿、该套件单跑 96/0 也绿 ⇒ 记为 flake,已在 RELEASE 行注明)。
3.16.0 — 修「查看」弹窗被压在设置底下 + 弹层白帧第三来源 + 真实模糊
3.16.0
三处真机问题的根因修复(全部靠真机读数定案):
① 设置 → Agent 预设 →「查看」弹窗被压在设置面板底下(点不到)
根因是插件自己:两条规则把宿主的层叠钉死了 —— [class*="_overlay"] { z-index: 2000 !important }(钉住设置弹层)、[role="dialog"] { z-index: 3000 !important }(宿主的设置面板自带 role="dialog",被钉到 3000)。而宿主的对话框挂在 portal root(position: fixed; z-index: 1000)里,层叠上下文一盖,里面的 dialog 再高也只能到 1000 ⇒ 永远输给设置面板。
这也解释了"把壁纸/插件关掉就正常":规则消失 ⇒ 宿主自己的次序恢复。
现在宿主的 _overlay / _overlayLayer / role=dialog 一律交还宿主层级,只抬我们自己的面板类。真机命中测试:设置打开时同形 portal root(z=1000)+dialog ⇒ DIALOG-WINS。
② 加号菜单 / 权限 / 上下文面板"只有一层白色滤镜、没有模糊"
三处的第一个带 backdrop-filter 的祖先都是输入框卡片 uV2eYG_card,它截断了弹层的 backdrop root。现在弹层打开期间临时摘掉这个已知包装容器的 blur(白名单 _card/composer/overlayAnchor/_seat/_stack;其它宿主面板一律不碰),并撤掉了上一版误加的"矩形相交"闸门(截断是 DOM/层叠性质,与几何无关)。
真机读数:弹层出现后 23ms 时已是 bg = 宿主色 58% + blur(11px),同时卡片 bf = none。
③ 弹层"打开要等一会儿才有底"的第三处来源:原生 popover API
showPopover() 打开时既不改属性、也没有子节点变动 ⇒ 前两条同步快路收不到信号(模型/推理选择器正是这种)。补了 capture 阶段的 toggle 监听,打开那一刻当场判定。
判据
popover-untrunc 19/0、anim-guard 19/0、fog-model 96/0、source-heal-token 10/0、panel-smoke 5/5、style-scope(0 RED / 0 REVIEW)、表面 token 命名空间 12/0;全量门禁步骤 1–11 PASS,第 12 步红点(新选择器未登记)已修并单独复跑两套判据全绿。
3.15.9 — 弹层显形同步打标(消灭白帧)+ 摘截断只碰已知包装容器
3.15.9
① 弹层"先白后变"的真根因:先插入(隐藏)→ 再靠 class/style 显形
上一版把"新增节点"改成同步打标,但弹层大多是先以隐藏态插入 DOM(display:none),随后通过 class/style 切换显形 —— 显形走的是 attributes 突变,而观察器只监听 childList,所以显形的那一帧没人管,画面上仍是宿主自己的不透明白底。
现在观察器同时监听 class/style/data-state/aria-expanded/hidden,属性突变的目标在同步快路里当场判定打标(MutationObserver 回调是微任务、跑在渲染之前)⇒ 显形的那一帧就已经带上我们的表面。另外:没有底的弹层不再要求"此刻可见"(隐藏时打标无害,显形即在位)。
② "摘截断祖先 blur"收紧为只摘已知包装容器
真机定案的截断者只有一类:输入框卡片这类"碰巧挡在弹层前面的包装"(类名含 _card / composer / overlayAnchor / _seat / _stack)。其余任何带 backdrop-filter 的祖先(标题栏里的子代理展开框、后台任务面板……)一律不碰 —— 那是可见的玻璃,摘掉就是"效果没了"。
代价:包在未知面板里的弹层会保持"半透明、没有模糊"(保守的一侧:绝不破坏可见的玻璃效果)。
③ 采纳外部审查的两条收紧
- 只在弹层矩形与祖先实际相交时才考虑摘(菜单飘在屏幕另一头时摘它纯属白丢磨砂);
- 撤除也瞬时:先注入"禁过渡 + 保持 none",下一帧再撤规则,避免反向播一次"清晰 → 磨砂"的跳变。
判据
popover-untrunc 19/0(撤除分两拍、非面板包装可摘、抖动修复)、anim-guard 19/0、source-heal-token 10/0、fog-model 96/0、panel-smoke 5/5;全量门禁 bash tools/check.sh --full PASS 12 / FAIL 0。
3.15.8 — 弹层同步打标(消灭白帧)+ 链内弹层恢复真模糊 + 抬升诊断标记
3.15.8
三处弹层交互收口(都来自真机反馈):
① "刚展开是白色不透明,过一会儿才变成模糊/半透明"
我们给弹层补的那层表面是 JS 判定后打标记的,旧路径要等 rAF 合并 + 动画闸门(最坏 ~400ms)⇒ 先出现的是宿主自己的不透明白底,几帧之后才切换。
现在改成同步快路:弹层插进 DOM 的同一个 mutation 回调里就判定并打标,不再等下一帧。真机实测:点击后第一帧采样(t≈44ms)已经是 bg = 宿主色 58% + blur(11px),白色过渡态消失。
② 加号菜单 / 权限 / 上下文面板"只有半透明、没有模糊"
三处的第一个带 backdrop-filter 的祖先都是输入框卡片 uV2eYG_card(blur(14px)):它把弹层的 backdrop root 截断了,弹层只能"糊"到卡片内部(一片纯色)⇒ 看起来只有半透明。模型选择器挂在 body 下、root 是整页,所以一直正常。
现在弹层打开期间会临时摘掉这个包装祖先的 backdrop-filter(一条 !important 规则,菜单关掉即逐字还原),弹层这才糊得到页面背后;如果那个祖先是面板本体(例如子代理展开框),我们一个像素都不碰(避免重演"玻璃被摘没")。另外修掉了"摘掉后下一轮又还原、再摘"的抖动(表现是同一个菜单时好时坏)。
真机复测:三处的 uV2eYG_card 读数变成 bf=none,弹层自身 bg = 宿主色 58% + blur(11px);展开框的玻璃未被误伤。
③ 新增一个诊断标记(不是修复)
"设置 → Agent 预设 → 查看"那个被压在设置底下的弹窗,我还没能复现到它(探针里找不到那个「查看」按钮)。已经加了 data-mpw-side-lift 标记:左栏子树里出现可见宿主弹层时就会打上(真机验证标记会随设置开/关出现/消失)。
但要说清楚:那个元素是 position: static,z-index 对它无效,所以这条目前只是诊断,没有修好。 拿到那个弹窗的真实 DOM 之后再定修法。
判据
popover-untrunc 18/0(新增 D5/D6/D6b:非面板包装可摘、抖动修复、关层还原)、anim-guard 19/0、source-heal-token 10/0、fog-model 96/0、panel-smoke 5/5;全量门禁 bash tools/check.sh --full PASS 12 / FAIL 0。
3.15.7 — 修弹层玻璃被饿死 + 摘截断不再摘掉宿主自己的玻璃
3.15.7
修 3.15.6 引入/暴露的两条真机回归(都是"看得见的玻璃不见了"),加一条地雷清理。
① 弹层表面被闸门"饿死"(白色滤镜、没有模糊)
3.15.6 为修侧栏收起动画加的共享闸门,判据是 document.getAnimations().length > 0 —— 这把留在动画表里的
finished 条目(CSS animation 带 fill: forwards 会一直留着)和永不结束的循环动画(光标闪烁/转圈)都当成了
"正在动画"。真机页面的动画表常驻 10 条 ⇒ 闸门每次登记、永不放行 ⇒ 弹层兜底底标记、右栏"只留最外层"标记、
侧栏抑制这些活全被饿死,四个弹层只剩宿主自己的不透明白底 + 我们的模糊 = 看起来"只有白色滤镜"。
现在只认 playState === "running" 且 iterations 有限的动画,并加"连续推迟到上限就无条件放行一次"兜底
(宁可多跑一次重活,也不能让功能被永久饿死)。真机复测:加号菜单 / 权限 / 模型 / 上下文四个弹层全部恢复
data-mpw-pop-bg + bg = 宿主色 58% + blur(11px)。
② 摘"截断祖先"时把宿主自己的玻璃也摘掉了(子代理展开框的模糊没了)
3.15.6 为了让弹层能糊到页面背后,会把第一个带 backdrop-filter 的祖先置为 backdrop-filter: none。
但那个祖先往往就是可见的那层玻璃(子代理展开框、输入框卡片)⇒ 摘掉它等于把好效果删了。
现在只在祖先没有可见底(纯包装,α < 0.05)时才摘;祖先自己有底时一个像素都不动,改为给弹层自己
打 data-mpw-pop-trunc 并用 88% 实底(糊不到页面背后,就不假装是玻璃)。宿主元素一律不碰、弹层关即还原。
③ 清掉与当前类型不符的 sceneKey
自愈写回时会清掉"类型是 mp4 却还挂着上一个场景 key"的粘性残留(今天是死字段,但属于"哪天被别的分支读到
就翻盘"的地雷)。
判据
anim-guard 19/0(新增 finished / 无限循环 / 兜底放行三条)、popover-untrunc 15/0(新增"D1–D4 有底玻璃
祖先不动 + 弹层实底可逆")、source-heal-token 10/0(新增清残留 sceneKey)、fog-model 96/0、
panel-smoke 5/5;全量门禁 bash tools/check.sh --full PASS 12 / FAIL 0。
另加真机排障出口 __mpwPopTagTest 与探针 popTag 读数(一眼区分"调度被饿死"与"条件不满足")。