dsh-bg-atelier · 底图工坊 (DSH 标准插件)
为 DSH Desktop 提供可更换底图与输入框特效的标准 DSH 插件。
随 DSH 启动自动加载,重启后保留(设置持久化到 host 侧文件 $DSH_HOME\dsh-bg-atelier\settings.json)。
安装后即随启动加载:本版是打包进 DSH web profile 的标准插件,开机即生效、可在 设置 → 插件 里开启/关闭。
目录结构
dsh-bg-atelier/
├── index.js # Host 半端 (ESM): 分类型供图路由 + /bga/wallpapers.json 清单路由
├── client.js # Client 半端: 图单与图库 / 限定范围换图 / 琉璃卡面 / 特效 / 设置页
├── cordis.patch.yml # bundle 挂载声明 (让 DSH 启动时挂载本插件)
├── package.json # npm 插件清单 (dsh.bundle.patch + dsh.client 客户端声明)
├── wallpapers/ # 内置底图目录 —— 每个子文件夹 = 一个"底图类型"(**原始文件**,PNG/JPG 原样,无损)
│ ├── 线稿风/ # 例如: 亚丝娜.png / 青缭.png / …
│ └── 重返未来1999/ # 例如: Vertin.png / 梁月.png / …
├── INSTALL.md # 安装 / 升级 / 卸载指南
└── README.md
安装(首次)
在 DSH Desktop 的任意会话里让 agent 执行(或直接在宿主 shell 运行):
dsh plugin --profile web add link:D:\DeepSeek\dsh-plugins\dsh-desktop-wallpaper
装完后重启一次 Harness/DSH Desktop,插件即随启动自动加载。
设置页顶栏会多出 底图工坊 入口;侧边栏底部出现「流光宝珠」换图按钮。
发布到仓库后(推荐)改为从仓库安装:
dsh plugin --profile web add https://github.com/Raylen-berry/dsh-desktop-wallpaper#main
放入/更换底图(按类型)
已发布图库:共 4 个类型、261 张底图(二次元 2 / 线稿风 5 / 重返未来1999 123 / 高清 131)。
clone 完先在插件目录跑一次 node tools/fetch-wallpapers.mjs(或设置页点「下载底图」)把图取回来,再重启 DSH;
设置 → 底图工坊 → 点类型卡进入图库即可选。图片不进 git(v1.5.5 起改走 Release 资产,见下面 A 节),
所以 clone 只有代码、很快;已发布图片为原始文件(无损,约 7.39 GiB,口径见 A 节)。本地另放的图片不一定包含在发布清单中。
加一个新类型/新图:把图片放进「放图目录」下一个子文件夹 = 一个类型,例如:
$wp = "D:\DeepSeek\dsh-plugins\dsh-desktop-wallpaper\wallpapers" # 或下面的放图目录
New-Item -ItemType Directory -Force "$wp\重返未来1999"
Copy-Item C:\some\*.png "$wp\重返未来1999\"
host 每次实时解析、按需刷新,设置页点「刷新」即出现新类型/新图(无需重启)。
放图目录解析顺序(首个有图的目录命中,① 最高):
$env:DSH_BG_ATELIER_WALLPAPERS 指向的绝对目录(显式覆盖)
$DSH_HOME\dsh-bg-atelier\wallpapers(推荐,插件启动时自动建好,随时往里丢图)
- 插件包内置
wallpapers/(随包分发,当作默认图集)
- 工作区相对路径
dsh-plugins/dsh-desktop-wallpaper/wallpapers(旧动态版兼容)
根目录若有散图(旧版遗留)会自动归入「未分类」类型;旧版根目录 URL 仍可访问(host 会自动按文件名在类型里找回),升级不丢当前底图。
高清细分
文件名去掉扩展名后,尾部带这些标记的会自动打上「高清」并可在类型图库内用 全部 / 高清 / 普通 筛选:
高清、_高清、·高清、-高清、(高清)、_4K、·4K、_HD、(HD)、_UHD 等(英文标记需要前置分隔符,避免误伤正常英文名)。
显示名 = 去掉标记后的名字(如 亚丝娜_高清.png 显示为 亚丝娜 + 高清 角标),不会把编号写进显示名。
功能
- 图库与图单:左侧按全部壁纸、我喜欢、最近使用、自建图单或原文件夹浏览;支持名称/类型搜索和清晰度筛选。
- 图单:可以新建、重命名、删除;卡片上的心形按钮加入“我喜欢”,加号可收录到一个或多个图单。
支持多选、全选搜索结果、批量加入及移出。图单只存收录关系,原图不移动、不复制;删图单也不删原图。
- 切换范围:顶部选择图单或文件夹,或在图库里点“设为切换范围”。“换一张”、侧栏宝珠和自动轮播共用这个范围。
浏览其它图单或搜索不会改变切换范围。空图单、缺失文件不会回退到全图库;删除当前切换图单会暂停轮播。
- 随机规则:在当前范围内采用轮次式 2/3 不重复洗牌,同轮内不重复。范围或成员变化时重新洗牌。
- 播放顺序与返回(v1.13.0):顶部“播放顺序”可选择随机或顺序,手动、宝珠、自动轮播同步遵循。
顺序播放按图单排列循环,文件夹按图库排列循环,暂时缺失的文件自动跳过。“上一张”沿本次打开页面后的选择记录返回,
再点“换一张”会沿记录前进;换范围后重新记,同一范围内移出的图不会被历史重新带回。
- 图单排序(v1.13.0):进入图单点“调整顺序”,拖动卡片下方手柄;也可用左右移动按钮,或聚焦手柄按 Alt+左右方向键。
排列自动保存;排序时显示完整图单,暂时停用筛选和多选,避免只对一部分图片排序。再次加入已有图片不会改变它的位置。
- 设置布局:大幅当前图预览 + 换一张/暂停轮播/喜欢/图单操作;下方分为“图库 / 外观 / 切换 / 动态壁纸”。
文件目录和内置图片下载收进“管理壁纸文件”;外观控件采用统一对齐,支持浅色、深色、窄窗口与键盘操作。
- 保存与恢复:图单、喜欢、最近 36 张和切换范围随设置保存;保存请求串行执行,失败时显示重试入口。
设置导出/导入同步保留这些信息,以及 WE 模式和画质偏好。大图单允许最多 2 MiB 的设置请求。
- 自动切换(v1.10.0):开关 + 间隔滑杆 —— 14 档不平均刻度(v1.11.0 起,见下),抽图与「流光宝珠」同一套轮次式
2/3 不重复规则。默认关。定时器只有一根:改开关、改间隔或换图时重起;只调外观不清零。间隔在读秒时还要再钳一次(NaN / 0 / 越界 → 1–120 分钟,再吸附到最近一档)——
setTimeout(fn, NaN) 等于 0ms,那是每秒换几千张图并刷爆 settings.json 的写法。
- 间隔档位(v1.11.0):
1 2 3 4 5 7 10 15 20 30 45 60 90 120 分钟,滑杆给的是等距的 0–13 号档位、
值由表查出(原生 step 只能等比,表达不了不平均刻度)。前 10 分钟占掉 6 档 —— 均匀 1 分钟一档时
「1→10 分钟」这段最常用的区间只占全程 8%,手感上等于没得调。手改过 settings.json 的存入值
(如 47)读写两侧都会吸附到 45,设置文件与界面不会各说一套。
- 渐变过渡:图库点击、侧栏宝珠、自动换图共用同一套切换控制,默认开启。
连点时当前这段渐变继续完成,只保留最后一次选择,随后从刚淡入的图继续渐变过去;
中间点击不会积压成播放队列。过渡中旧图与下层新图都保持不变,避免半透明旧图下面突然换图。
手动点击会按节奏即时加速正在进行的渐变,最新目标也使用该次点击对应的时长。v1.15.0 的档位为:
两次点击间隔 ≥1500ms → 原设置;800–1499ms → 最长1000ms;400–799ms → 最长500ms;<400ms → 最长300ms。
第一击、停顿 ≥1500ms 后恢复原设置;只缩短、不把更短的原时长拉长。记录点击时刻而非图片解码完成时刻,
所以慢图不会误判为慢点。快速连点会跳过“开始前等待”;自动轮播与启动恢复不参加计频,也不继承快档。
当前动画从现有进度提高播放速度,不重置透明度;同档反复点击不延后完成时刻。上述档位表示完整一段渐变的时长,
已播放一部分的动画只加快剩余部分。每次点击仍推进选图;极快连点中的中间图可能不完整显示,画面加速追上最后一次选择。
下一段的起点禁用 transition 并先显示一帧,再开始淡出,防止浏览器把上一段的透明度从 0 反向动画到 1。
双 rAF 保证起点与终点分帧;从实际提交终点后开始计时,computed opacity 不可见才拆层,
主线程阻塞时不会按插入层的墙钟时间强拆。清空、关闭渐变、WE 接管、插件卸载均取消排队。
系统开启减少动态效果时直接切换。
- 换图重置自动切换间隔:手动、宝珠、自动换图都从最新切换重新计时;
仅调整暗纱、配色或其它外观参数不重置计时。
- 后台暂停(v1.15.1):窗口失焦、隐藏或冻结时停止计时并取消未上屏的换图;
回到前台保留最后一张已加载的图,重新计算完整间隔,不补播后台错过的切换。
- 过渡参数:响应时间 0–1000ms(开始淡出前的等待);渐变时长 100–5000ms。默认 0ms / 900ms。
新图解码成功后才接受切换;加载错误或 15 秒超时保留原底图,避免露出空白背景。
连点只保留最新目标,过期解码结果不会上屏;清空、换范围、WE 接管或卸载时解除旧加载引用。
- 连点负载控制(v1.15.0):每次点击仍推进选图位置;解码任务串行执行,只保留一个最新待处理目标。
当前渐变结束后才加载下一目标,跳过赶不上显示的中间图,避免原图解码、预览重绘与保存请求堆积。
相同图片共享正在进行的解码;失败或超时保留当前图,有新目标则继续处理。
v1.3.0 起不再提供「对话页固定宽度」:那一节(开关 + 640–3840px 滑杆 + 常用宽度快捷键)
已整体移到 dsh-cache-control 的设置页 「会话策略」→ 对话页。钉的是同一组
--dsh-chat-content-width / --dsh-composer-card-max-width / --dsh-chat-user-width
变量,两边同时开只会互相覆盖,所以本插件这边彻底删净。数值不用重设:cache-control 的
host 半在启动时发现自家 settings.json 缺 chatWidth / chatWidthEnabled,就一次性从
$DSH_HOME\dsh-bg-atelier\settings.json 搬过去并写盘。本插件此后不再碰这些字段。
发布前检查(CI 与本地同一条命令)
push / PR 都会跑 .github/workflows/ci.yml,它只做一件事:npm test。本地跑的就是同一条命令,
不装任何依赖、不联网、不做任何真实下载:
npm ci # 首次安装开发测试依赖(React,与宿主 18.3.1 对齐)
npm test # = node tools/run-all.mjs
node tools/run-all.mjs --list # 只看清单:跑哪些、以及哪些被排除、为什么
tools/run-all.mjs 把每套都跑完再汇总,任一套非 0 退出 ⇒ npm test 退出码 1 ⇒ CI 变红。
CI 用 Node 20/22/24 三档矩阵、windows-latest。
本机实测(Node 24.20.0):语法检查 18/18、离线套件 14/14 通过。重点回归:
| 套件 | 本机结果 |
|---|
tools/test-download-robustness.mjs | 42 项通过(自带假 HTTP 服务,零请求出网) |
tools/verify-dockfx-bounds.mjs | 全部 PASS |
tools/verify-background-lifecycle.mjs | 后台停表、迟到回调、解码中断、渐变中断、恢复与卸载通过 |
tools/test-playlists.mjs | 更名后的收藏、图单、最近使用及构图迁移通过 |
另用隔离 Chromium 检查后台 10 分钟后恢复、完整间隔重新计时、自动和手动换图的实际截图像素。
未纳入 CI 的步骤(原因同时写在 tools/run-all.mjs 的 EXCLUDED 里):
tools/fetch-wallpapers.mjs --check(只读校验本机原图,不联网;要已备好 261 张约 7.39 GiB 底图,图片不进 git ⇒ CI 上必然失败)、
tools/test-served-bytes.mjs(要 wallpapers/ 里的真实图片才能起供图路由断言,离线实测退出码 1)。
换台机器:可迁移性与必须手动的步骤
给后续在任何一台机器上接手的人或 agent:装本插件不需要任何手工点击(不像
dsh-browser-live 要装浏览器扩展),但下面几条必须先看清楚。
(起因:用户 2026-09-12 反馈"工作电脑上传、回家发现可用性很差、必须手动操作"。)
A. 克隆体积(v1.5.5 起:图不进 git,改为 Release 资产 + 按需下载)
已发布底图合计约 7.39 GiB(现 261 张;Release tag wallpapers-v1 与清单同步为 261 个资产),长期放在 git 里会让每次克隆都变成几百 MB(用户换机时"装个插件要拉几百兆"就是这么来的)。
加图后的发版流程:node tools/make-manifest-append.mjs --from <上一版清单> → node tools/make-release.mjs(对账+补传+逐张回验,可断点续传)。
仓库只留 wallpapers.manifest.json(每张图的路径 + 字节数 + sha256),图片作为 Release 资产发布(tag wallpapers-v1):
git clone https://github.com/Raylen-berry/dsh-desktop-wallpaper.git # 只有代码,很快
cd dsh-desktop-wallpaper && node tools/fetch-wallpapers.mjs # 从 Release 取回全部(可重入/断点续传)
node tools/fetch-wallpapers.mjs --check # 只校验本机现有图(不联网)
画质口径:完全无损 —— 不缩放、不重编码。 Release 资产就是原始文件(PNG / JPG 原样),逐张 sha256 与清单一致。
下载量确实大(7.39 GiB),这是有意换来的:底图是长期资产,宁可下载慢,也不要在存档上留一次有损编码。
显示这一侧现在也不打折(v1.6.1 起):host 供图不设尺寸上限,把原图字节直接送给浏览器 ——
5120 / 7680 长边的超宽屏、8K 屏全都吃满,不会再被 3840 拉成放大模糊(此前 SERVED_MAX_DIM = 3840
会先在宿主里缩到 3840 再送)。代价是浏览器要解码整张 30–44 MP 的图:单张解码后约 120–175 MB 内存、
切图首帧多等几百毫秒 —— 换的是大屏上的清晰度;而且送原图这条路上 sharp 完全不参与,
省掉了一次「解码 + 重编码」的 CPU 与首字节等待。派生图(图库 640 / 当前底图 320 / 类型卡 112 px)
另走一套,不受影响。真要一份轻量版:node tools/compress-wallpapers.mjs 可另生成一套 3840 宽 WebP q92
到 wallpapers_light/(仅供自用,不参与发版)。
回归测试(不用重启 DSH):node tools/test-served-bytes.mjs —— 用假 ctx 调 apply() 把路由处理器抓出来
直接请求,断言原图那条路逐字节等于磁盘文件、?sz=thumb|preview|poster 仍在缩放、404 与路径穿越防护仍在。
设置页里同一个入口是「下载底图」按钮(显示进度、逐张校验 sha256;已存在且校验通过的跳过 ⇒ 断网了再点一次即可)。
下载的健壮性参数(fetch-wallpapers.js 的 fetchWallpapers(opts),host 路由与命令行共用这一份)
timeoutMs:单张的时间预算,默认 300000(5 分钟)。超时按"这一张失败"处理并走既有退避重试,
不会让任务永远停在"下载中"。覆盖方式:fetchWallpapers({ timeoutMs: 60000 })。
默认值的依据:清单里最大一张是 63283616 B(60.4MB),5 分钟意味着 ~1.7 Mbps 的慢线也能下完,
而正常家用宽带(20 Mbps 以上)一张只要几秒 —— 既不误杀慢线,也不让真卡死的连接赖着不走。
retries:单张重试次数(不含首次尝试),默认 2,必须是非负整数(非法值回落 2)。
retries: 0 表示只试一次,真的不重试。
signal:外部 AbortSignal。触发后立即停止且不再重试,错误消息会写明"已取消"。
- 下载是流式的:边收边写
.part、边累计 sha256,字节数一超过清单值就立刻中止 ——
不会把整张图先读进内存(最大 60.4MB)再校验。校验通过才 rename 到最终路径。
这些行为的离线断言:node tools/test-download-robustness.mjs(不联网,把 fetch 打桩、
写入临时目录,覆盖超时/取消/字节数不符/哈希不符/正常落盘,共 42 条断言)。
加图/改图必须用追加式清单生成器:tools/make-wallpaper-manifest.mjs 是从零重编号的,
一改名或加图就会让既有 wNN 与 Release 里已上传的资产整体错位(贝利尔.png→贝利尔2.png 就撞过
w08/w16),make-release 会因为"同名资产字节数不符"把已传的删掉重传。发版一律走
node tools/make-manifest-append.mjs(默认拿 HEAD 那份清单作基准,按 sha256 把已发布的图绑回原资产名,
只给新图续编 w20、w21…),再 node tools/make-release.mjs 补传差额。
迁移顺序(重要):先把图作为 Release 资产发布并验证下载可用,再把 wallpapers/ 从 git 移除;
反了的话,新克隆在 Release 就绪前一张图都拿不到。图片从 git 移除之前,git sparse-checkout add wallpapers
仍可按需从 git 取图(离线机器适用)。
B. 装(agent 可全自动)
dsh plugin --profile web add link:<你放插件的绝对路径>
link: 挂载 ⇒ 改完即生效。装完必须重启 DSH Desktop:client 半在服务启动时 compose
(与 dsh-cache-control 同理,刷新页面无效)。重启会掐断正在跑的会话轮次 ⇒ 让用户自己挑时间。
C. 底图在哪 / 设置在哪
- 底图在插件目录自己的
wallpapers/<类型>/ 下(原始文件、不进 git ⇒ 换机后先按 A 节从 Release 取回);
往里加图后派生图(640px 图库图 / 112px 类型卡迷你图)会自动生成。
- 设置(当前底图 / 特效 / 配色 / 卡面不透明度与模糊 / 卡面阴影开关)在
$DSH_HOME/dsh-bg-atelier/settings.json,不在仓库里 ⇒ 换机器后是默认值:
特效回到「流萤」、卡面阴影为开、底图要重新选一张 —— 这是最常见的"装好了但看着没变"。
- 特效与底图已解耦(v1.5.1 起):没有底图也照样画特效。若在老版本上遇到
"点了清除底图 ⇒ 特效全无",那是 v1.5.0 及以前的旧 bug,升级即可。
D. 已知的宿主坑:插件会被 generation 迁移搬走(本机踩过)
部分 DSH Desktop 版本启动时做 installGeneration 迁移,会把 link: 挂载的插件重新 stage,
期间把一个绝对路径当相对路径拼接 ⇒ ENOENT、迁移被 defer,插件也可能不加载。
本机的处置是给应用 bundle 打本地补丁(把本插件加进 KEEP_IN_SHARED_TREE)——该补丁不在本仓库里,
它属于"每台机器各自的 DSH 应用目录"。识别方法:启动日志出现 migration deferred / could not stage,
或 profiles/web/.generations-deferred.json 反复出现。DSH 每次升级都会覆盖该补丁,升级后要重跑。
F. 设置导出/导入(换机器一键搬配置,v1.5.4 新增)
node tools/settings.mjs export --out D:\bga-settings.json # 旧机器
node tools/settings.mjs import D:\bga-settings.json --yes # 新机器(覆盖前自动备份 settings.json.bak-*)
show 看当前值;不带 --yes 是演练模式(只打印将要写入什么)。导入只做表层校验 + 区间钳制
(本插件 host 是原样存取、不 sanitize,所以钳制在这儿做严);底图结构不合法时置空并提示,
底图图片不在导出文件里(脚本会检查本机有没有这张图,缺了就提示去 git sparse-checkout add wallpapers)。
导入后仍需重启。
E. 换机后自查(30 秒)
node tools/extract-real-css.mjs # 期望 PASS(含数量随屏宽 / 阴影独立开关 / DockFx 真渲染三条)
node tools/verify-dockfx-bounds.mjs # 期望 PASS
设置页 →「底图工坊」→「对话框」应看到:卡面不透明、卡面模糊、卡面阴影勾选框、
四个特效(流萤 / 气泡 / 落樱 / 雨丝)+ 关闭。
卸载
dsh plugin --profile web remove dsh-bg-atelier
或在 设置 → 插件 里停用/移除该插件后重启 Harness。
技术要点 (debug 备忘)
- Client 用
window.__ModuleLoader__.load({ id, factory }) 包裹,exports.apply/exports.inject。
- 底图清单走
/bga/wallpapers.json HTTP 路由(返回 { total, categories:[{name,count,hd,items}] }),不再用运行时-only 的 host.call 桥。
- 供图 URL:
/bga/wallpapers/<编码类型名>/<编码文件名>(旧格式 /bga/wallpapers/<文件名> 仍兼容,自动按文件名在类型里找回)。
调试可直接访问:/bga/wallpapers/%E7%BA%BF%E7%A8%BF%E9%A3%8E/%E4%BA%9A%E4%B8%9D%E5%A8%9C.png(含路径穿越防护,../多余斜杠返回 400)。
- 样式自包含注入(
data-bg-atelier-styles),不依赖 styles 全局。
webServer prefix 路由匹配规则 pathname === prefix || startsWith(prefix + '/'),注册路径不带尾斜杠。
- Host 日志
[dsh-bg-atelier](harness 控制台),Client 日志在浏览器 DevTools。
- 本地底图去重只能建硬链接,不能删名字:图库列表是实时扫盘(
scanTypeDir/listTypeDirs 走 fs.readdir),
wallpapers/ 下每个受支持文件都会变成设置页里的一张图 ⇒ 删掉一个重复名字会改变用户看到的列表。
用硬链接则两个名字都还在、共享同一份字节(同一 inode),列表/URL/已有设置里的引用全不变,磁盘只存一份。
工具:node tools/dedup-hardlink.mjs [--dry-run|--pairs];断言:tools/verify-wallpaper-dedup.mjs(在 run-all.mjs 的 SUITES 里)。
⚠️ node:fs 的 linkSync 在这台机器/卷上会原生崩进程(exit 0xC0000409,STATUS_STACK_BUFFER_OVERRUN,
没有异常栈、进程直接消失),所以工具里建链走 PowerShell 的 New-Item -ItemType HardLink(CreateHardLinkW),
扫描/哈希/判定仍留在 node。
- 硬链接不影响仓库体积:
/wallpapers/ 在 .gitignore 里(底图走 Release 资产、不进 git),
所以去重只省本机磁盘,git clone 的体积一个字节都不变 —— 别把这两件事混为一谈。
版本
-
v1.15.2:新增 16 组普通版与高清版壁纸,共 32 张,发布清单从 229 增至 261 张,全部保留原文件字节。
同步本地已有的「冷周六1」「图图星锑1」编号,保持原下载资产名;旧设置里的当前底图、收藏、图单、最近使用与构图引用自动迁移。
-
v1.15.1:后台暂停自动轮播,恢复时重画当前底图并重新计时;过期计时器、解码及渐变回调不能续播旧任务。
统一“贝丽尔”“以影相之”的拼写,普通版维拉补齐编号 2;已保存的底图、收藏、图单、最近使用和构图随更名迁移。
-
v1.15.0:调节点击节奏边界为 1.5/0.8/0.4 秒,对应原时长/1000/500/300ms。
原图解码改为串行并合并最新目标,渐变过程中不为中间图重绘预览;缓存未变的样式与主题计算、减少图库重绘。
新增隔离浏览器压力回归:验证密集点击仍准确推进选择,同时限制解码并发和界面更新次数。
-
v1.14.0:手动渐变按点击频率分档加速(原设置/1000/600/300ms),当前动画保留进度即时提速,快速连点跳过开始前等待。
同档连点不重新计时;停顿恢复,自动轮播不受影响,原渐变设置不被改写。保留解码等待、独立构图与连续渐变保护。
-
v1.13.0:随机/顺序播放、上一张与前进记录、图单拖拽及键盘排序;每张壁纸独立保存缩放和焦点,渐变两层分别保留构图。
图单顺序、播放模式、独立构图均随设置导出/导入保留。重启 DSH Desktop 后加载新版本。
-
v1.12.0:图单与设置页重构。新增多图单收录、喜欢、最近使用、批量整理和限定图单/文件夹切换;新布局分为四个页签。设置请求上限扩至 2 MiB,保存串行化并显示失败重试。保留连续渐变修复。
升级需重启 DSH Desktop 一次,使客户端与保存路由同时加载新版本。
-
v1.11.0:切换间隔改不平均档位 + 过渡参数可调 + 连点不再闪回 + 换图重起自动切换
- 连点护栏(实测出来的 bug):连点换图时每一趟都
fadeStop() 拆掉在动的那层、另插一层画同一张旧图,
但那层从 opacity:1 起步 —— 屏幕上那一刻是"旧图 × 当前透明度"(2 秒的过渡里点到第 800ms 就已经只剩 0.6),
于是画面先闪回全不透明再从头淡一趟,而且每次点击都把倒计时归零 ⇒ 用户看到的就是"连点时渐变失效、
点的图迟迟不出现"。真机抓到的证据(MutationObserver 记录 data-bg-atelier-fade 层的增删 + 每 40ms 采
::after 的 computed opacity):修之前三次连点各产生一次 REMOVE + ADD(opacity:1);修之后只有第一次
ADD,后两次点击不产生任何层增删,透明度单调下降。
- 拆层也不许信墙钟(第二轮的"卡没渐变,变成闪变"):同一套仪器抓到的另一件事 —— 换图那一帧
主线程被卡 785ms(
PerformanceObserver('longtask') 直测),rAF 停 ~950ms,::after 的过渡起手
被推迟到 ~900ms,于是"插入 + 延迟 + 时长 + 200ms"这个墙钟拆层点会落在过渡还没走完的时候:
实测那一刻 opacity 还有 0.24,摘掉它 = 屏幕直接从"0.24 旧 + 0.76 新"跳到全新 = 闪变。
现在拆层前先读 computed opacity(fadeVisible()),没淡完就 200ms 后再看(最多 60 次);
同一次实测里拆层从墙钟的 2434ms 推迟到 3828ms,那一刻 opacity 已经是 0.000005(单调、无回跳)。
- 换图重起自动切换:判据从"signature 变了"改成"屏幕上的图变了" —— 手动换到满意的那张之后,
间隔从这一张开始算,不会再被刚走完的旧表立刻换走。只调暗纱/配色仍然不重起(免得间隔永远走不满)。
- 间隔档位:滑杆从「1–120 分钟均匀 1 分钟一档」改成 14 档不平均刻度
1 2 3 4 5 7 10 15 20 30 45 60 90 120。原生 range 的 step 只能等比,所以滑杆本身走等距 0–13,
值由 AUTO_STOPS 表查出(nearestStop 吸附,正好卡中间取小的那档,结果确定)。
Slider(...) 多了一个可选的第 7 参 stops,其余 6 个调用点一行没改。显示文本按值算(30 分钟 / 2 小时),
不是档位序号。坏值(NaN / 非数字)仍兜 30 分钟,兜底值本身也在表里。
- 过渡参数:新增「响应时间」0–1000ms 与「渐变时长」100–5000ms 两个滑杆,都从 里读、
坏值各有兜底(900ms / 0ms)。响应时间的实现是换图后先按原样多盖一会儿,到点才写终点帧 ——
默认 时走的还是原来那条「下一帧就淡」的路径,行为与 v1.10.0 完全一致。
连换两张时用一个层 token 挡住上一层的迟到回调,不然它会把新层直接推到终点帧(等于不淡)。
渐变时长上限是 2000ms → 5000ms 放开的(实际上限"够慢还能看"就在这里:再长就是两张图长时间叠着);
响应时间那头的钳制从 5000 收成 1000,跟滑杆对齐 —— 否则手改 塞个 3000,
值生效了但滑杆指不到那个位置(拇指贴边、数字却更大)。滑杆上限与钳制上限的一致性由套件守(见下)。
WE 壁纸库(v1.9.1)
可按名称、标签或编号搜索,并按场景、视频、网页筛选;筛选不会更换当前背景。当前背景区可切换实时/静态模式或手动重新连接。
v1.9.0 增加场景属性面板:音量、播放倍率、鼠标视差、翻转、主题配色,以及从壁纸读取的人物、背景、音频等分组。滑块只修改草稿,点击「应用到此背景」才一次性发送;支持放弃未应用修改、按壁纸保存和加载预设及恢复默认,独立保存在 DSH 配置目录 we-scene-properties.json。不修改订阅文件,不把更改应用到 Windows 桌面壁纸。自定义图片等文件属性暂不提供导入;属性里的条件和脚本不会执行。
实时采集提供 30 / 45 / 60 帧目标,默认「均衡」45;显示实际出帧和尺寸。保留原尺寸、原鼠标对齐,不强制缩小采集图像:本机同场景缩放会使帧率降到 11–13,原尺寸 30 帧档约 28.4,45 / 60 帧档约 35,45 档的最长帧间隔更短。帧率取决于机器负载和场景,不能保证稳定 60。视频播放后隐藏后备图,状态更新不再重建主题样式;原生窗口仅变更层级时不重复触发尺寸调整。
从旧版升级需重装原生桥并完整退出、重启 DSH,加载新增属性接口。没有修改 WE 全局画质。
v1.8.1 修复正式桌面权限导致实时场景退回静态图的问题;从 v1.8.0 升级需要重新运行原生桥安装器并完全退出、重启 DSH Desktop。页面内部导航现在保留实时连接,连接失败会留下可查错误。
在「底图工坊 → Wallpaper Engine 库」选择壁纸。场景新增两种模式:
- 实时 + 鼠标跟随:WE 原引擎运行场景,原生桥把专用窗口画面接入 DSH。保留场景自身的动画和鼠标位置驱动效果,默认 45 fps 目标、可选 30 / 60;需要 WE 已运行,以及已安装并重启生效的桌面桥。
- 静态近似:保留 v1.7.1 的有界工作线程合成,不需要 WE 运行。实时连接失败时也保留静态画面并显示原因。
实时模式只读取鼠标位置,不转发聊天中的点击和键盘。窗口移动、缩放时跟随;最小化/隐藏释放实时场景,恢复时重连;清除背景、切换壁纸和卸载客户端时停止视频轨道与专用窗口。选择壁纸不改变手动配色,「采用壁纸配色」才会保存明确选择。
原生桥需要 Windows。安装、源代码构建、权限范围、更新后的重装及回退见 we/native/README.md。新增桌面桥后必须完全重启 DSH Desktop,仅刷新页面或重启 Harness 不够。 DSH 更新可能覆盖入口;插件会提示桥未加载并退回静态模式。
库和媒体
支持 workshop 订阅以及 projects/<项目>、projects/<组>/<项目> 本地结构;本地 ID 取相对路径哈希,跳过目录链接,不遍历项目素材目录。图库和媒体共享 60 秒扫描缓存,手动刷新强制重新发现。
WE 状态取进程信息,端口只作诊断。订阅和本地项目均可通过官方 CLI「在 WE 打开」。视频静音循环播放并支持 Range;web 仍为不可点击的沙箱背景,不保证 WE 专有网页 API 兼容。
静态合成仍支持部分 PKG/TEX/LZ4/DXT/PNG,采用单工作线程、八项等待队列、45 秒超时、一分钟失败冷却和尺寸/字节限制。它不完整渲染 scene 动画和特效;实时模式才使用 WE 引擎。旧静态缓存继续兼容,尚未增加源场景改变后的自动失效。
验证(2026-09-24)
- 18 项语法检查、10 套离线测试通过;新增原生接口边界、安装器幂等性、客户端取消/迟到流/隐藏恢复清理测试。
- 本机库扫描:22 项,21 个本地项目(含 WE 内置项目)、1 个订阅。
- 完整 DSH 页面最后 10 秒实测约 30.9 fps(原基线约 28.4),309 帧、报告丢帧 0;独立实例约 35 fps 不代表完整页面性能。曾遇到一次原生窗口关闭,最后复查未再出现,原因尚未确定;短时采样不是长期稳定性保证。
- 正式插件客户端集成:初次播放 984×660,窗口缩放后 1134×710,最小化恢复建立新流,画面继续更新;输入框命中和清除断言通过。
- 原生鼠标坐标通过专用 SceneScript 夹具核对。壁纸必须自身支持相应鼠标效果;点击、拖动和键盘交互不会透传到壁纸。
- 实时模式会额外运行一份场景,性能高于静态图的消耗;多屏跨 DPI、长期稳定性和 4K 压力尚未完整验收。场景声音通过属性面板控制,默认静音。
本地素材不随插件发布;个人配色与当前底图设置不由安装器重置。v1.7.1 已经覆盖前的配色没有历史记录,无法自动恢复。