# dsh-mpkg-wallpaper — DSH 壁纸引擎背景插件 [![Awesome DSH Plugin](https://awesome-dsh-plugin.com/badge.svg)](https://awesome-dsh-plugin.com) [中文](README.md) | [English](README.en.md) 给 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) Web 界面(`dsh web`)添加背景壁纸的插件:**Wallpaper Engine `.mpkg` 解析、Steam 创意工坊目录、视频/网页/图片壁纸、时间变化壁纸的多时段切换、整屏虚化体系、主题色与玻璃外观、本地壁纸库、定时轮换、Now playing 控件、一键更新**。外观细节几乎全部可调。 > 版本口径:本文件描述的是 `package.json` 里 **`3.10.0`** 这一版实现。发布面共 **15 个文件**(`lib/` 8 个运行时文件 + `package.json`、`icon.svg`、`cordis.patch.yml`、`README.md`、`README.en.md`、`THIRD-PARTY.md`、`LICENSE`;`npm pack --dry-run` 实测 15 文件 / unpacked 2 088 240 B);`lib/liquid-glass/**`、`lib/liquid-glass-bundle.js`、`dist/`、`tools/`、`docs/` 都不进 npm 包(`package.json:8-21`)。本轮的默认档变化:**`npNowPlaying` 关 → 开**(3.8.0 起)与 **`powPauseHidden` 关 → 开**(3.9.0 起,只迁移"从没设过"的存量档;详见[这一版新增/变更](#这一版新增变更))。 --- ## 下载 · 安装 插件已发布到 npm(`dsh-mpkg-wallpaper`)。四种装载方式——先按这张表选一条,再看对应小节: | 方式 | 适合谁 | 更新怎么做 | 客户端界面 | |---|---|---|---| | 一 `dsh plugin add`(推荐) | 默认选择;市场能识别「已安装」 | `dsh plugin --profile web update …` | 完整 | | 二 pnpm 手动装 | 自己管 profile 的依赖表 | 同上(走依赖表) | 完整 | | 三 GitHub 克隆 | 开发者 / 离线 / 要改代码 | `git pull` | 完整 | | 四 单文件 bundle | 离线应急;给非 DSH 宿主复用路由 | 重新生成并替换那个 `.mjs` | **只有宿主端** | ### 方式一:`dsh plugin add`(推荐,市场可识别) ```bash dsh plugin --profile web add dsh-mpkg-wallpaper # 重启 dsh web 后浏览器 Ctrl+F5 生效 ``` ### 方式二:pnpm 手动安装 ```bash pnpm --dir $DSH_HOME/profiles/ add dsh-mpkg-wallpaper # 重启 dsh web,浏览器 Ctrl+F5 生效 ``` 与方式一同源,只是不经 `dsh plugin` 包装。 ### 方式三:GitHub 克隆(开发者 / 离线) ```bash git clone https://github.com/XHR666/dsh-mpkg-wallpaper.git $DSH_HOME/profiles//node_modules/dsh-mpkg-wallpaper # 然后在 profile 的 cordis.patch.yml 注册: # - insert: # - id: dsh-mpkg-wallpaper # name: dsh-mpkg-wallpaper # 重启后生效 ``` > 方式三不写依赖表 ⇒ 市场不显示「已安装」(只影响显示,不影响功能)。 ### 方式四:单文件 bundle(离线 / 拷文件即装;**只装宿主端**) 把宿主端内联成一个自包含 ESM 再登记: ```bash cd /path/to/dsh-mpkg-wallpaper node tools/build-bundle.mjs # 产物:dist/dsh-mpkg-wallpaper.bundle.mjs(实测 449 671 B / 439.1KB;以 bundle-equivalence-test 的输出为准) node tools/build-bundle.mjs --check # 与源码对拍:导出面 / 路由表 / ping JSON 形状(20 条断言) node tools/bundle-equivalence-test.mjs # 更全的等价性门禁(38 条断言;门禁第 11 步) ``` 把 `dist/dsh-mpkg-wallpaper.bundle.mjs` 拷到任意目录(例如 `~/.dsh/plugins/`),在 profile 的 `cordis.patch.yml` 里按**绝对路径**登记,然后重开 `dsh web`: ```yaml # $DSH_HOME/profiles//cordis.patch.yml - insert: - id: dsh-mpkg-wallpaper name: /绝对路径/dsh-mpkg-wallpaper.bundle.mjs # ← 指向那个 .mjs 文件本身 ``` **这条路装载了什么 / 没装载什么**(都是代码与门禁事实): | 项 | 方式四的行为 | 依据 | |---|---|---| | 宿主端(上传/Range 流式播放、场景提取、音频清单、设置持久化、诊断上报等 **41 条路由**) | **完整**(`lib/index.js` + `pkg-extract.js` + `web-wallpaper.js` + `web-interaction.js` 全部内联;外部依赖只有 node 内建) | `node tools/bundle-equivalence-test.mjs`:路由表(kind + path)逐条相同 `[41 条]` | | `/api/mpkg-wallpaper/ping` | `{ok, version, betterSidebar, betterSidebarVersion}` 键集合与源码一致 | 同上 + `build-bundle.mjs --check` | | **客户端半(设置面板 / 壁纸层 / 磨砂 / Now playing)** | **不装载**。单文件里只有宿主端导出面(`apply` / `inject` / `__mpwTest`) | 客户端半由 DSH 客户端模块系统按**包**发现:扫描宿主 Loader 条目里声明了 `dsh.client` 的包并解析其 `exports["./client"]`;裸 `.mjs` 没有 package.json ⇒ 没有 `dsh.client` 声明 | | `GET /api/mpkg-wallpaper/lg/*`(遗留 WebGL 托管路由,客户端已不调用) | bundle 旁边没有 `liquid-glass/` 时 **404**;`cp -r lib/liquid-glass /` 即与源码逐字节一致 | 该路由以 `import.meta.url` 定位同目录 `liquid-glass/`(`lib/index.js:3453`);门禁两种布局都断言过 | | `ping.version` | 上一级目录没有 `package.json` 时返回 `null`(只影响版本号显示) | `new URL('../package.json', import.meta.url)`(`lib/index.js:1622`) | | 「检查更新 / 一键更新」 | 无伴生 `package.json` 时 `update-check` 返回 500,`update-apply` 会往 bundle 同级/上级目录写文件 ⇒ **不建议在方式四下使用** | `lib/index.js:1792-1860` | | 卸载 | 删掉那个 `.mjs` 与 `cordis.patch.yml` 里那一行即可 | — | > 结论:**方式四是"宿主端能力"的降级装载**(离线/应急/给非 DSH 宿主复用路由时好用);要完整界面请用方式一/二/三。产物**不入库**(`dist/` 在 `.gitignore` 里:它是 `lib/*.js` 的纯派生物,两次构建 sha256 逐字节相同,`tools/bundle-equivalence-test.mjs` 第②节;发布时现生成并公布哈希)。 ### 更新 ```bash # 方式一 / 二:走 npm 的 latest 标签 dsh plugin --profile web update dsh-mpkg-wallpaper # 方式三:在克隆目录里 git pull # 方式四:重新生成并替换那个 .mjs node tools/build-bundle.mjs ``` 更新后都要:重启 `dsh web` → 浏览器 `Ctrl+F5`。 ### 卸载 方式一/二/三:`dsh plugin --profile web remove dsh-mpkg-wallpaper`。 方式四:删 `.mjs` + `cordis.patch.yml` 里那一行。 残留数据(可选清理):浏览器 `localStorage['dsh.mpkg-wallpaper.v2']`、宿主端 `~/.dsh-mpkg-wallpaper/`(`settings.json`、`web-store.json`、`media-audio.json`、上传的 mpkg、转码缓存、`diag-*.json`)。 ## 30 秒快速开始 这节给最短路径:装完到看见壁纸,只走三步。 1. **装好并重启**:按上一节任选一种方式装完,重启 `dsh web`,浏览器 `Ctrl+F5`。 2. **打开面板**:左侧栏「设置」→「壁纸引擎背景」。 3. **选一张壁纸**,任选其一: - 拖入 `.mpkg` 文件(视频类直接播;场景类走静态帧/图层合成) - 选本地图片 / 视频,或填一个图片链接 - 「自定义目录」选一个文件夹(可直接选 Steam 的 `steamapps/workshop/content/431960`,每个子文件夹算一张) 默认档就已经能用:总开关开、大文件混合模式开、整屏虚化开(30px)、Now playing 挂在左侧栏。 想微调,先动这三处就够:**壁纸设置 → 磨砂模糊**(0–40)、**界面统一 → 整屏虚化程度**(0–40)、**壁纸设置 → 镜头缩放**(10–2000%)。 > 没反应时先去「其他」tab 点一次 **一键诊断上报**(宿主不可用会自动下载 JSON),再带上它去[反馈](#反馈-bug)。 ## 核心能力 这节按**你能感知到的东西**分组(来源、时间变化、虚化、外观、播放、库与轮换、安全、备份),不按代码模块。 **📦 壁纸来源** - **Wallpaper Engine `.mpkg`**:浏览器内直接解析容器(不上传第三方);视频类播放内嵌 mp4 / 视频纹理;场景类解析容器提取素材;**时间变化**按系统时间选时段素材 - **Steam 创意工坊目录**:自动发现 WE 安装(注册表 + `libraryfolders.vdf`,支持非默认盘),列出 `video / web / scene` 三类;也可把 **workshop 主目录**(`steamapps/workshop/content/431960`)直接设为自定义目录——每个子文件夹自动识别为一张壁纸 - **视频**:`.mp4/.webm/.mov/.m4v` 直接播放;**网页**:HTML 在沙箱 iframe 中加载(带风险预检);**图片/动图/链接**:本地图片或 URL(含 `data:image`) - **自定义目录**:任意文件夹,`.mpkg`、workshop 子目录、图片/视频/`scene.pkg` 混放都能识别 **⏰ 时间变化壁纸(Time Variation)** - 识别 WE 的时间变化属性(`morningtime / daytime / dusktime / nighttime / timevarying`,默认 5/8/17/20 时,`lib/client.js:10419-10423`) - **按需懒加载**:只提取当前时段素材(单槽峰值几十 MB),切换时段时才读,避免一次导入全部时段导致 OOM - **手动锁定时段**:时段按钮只在容器里真的有该时段素材时出现(`lib/client.js:12797-12813`),键名 `timeOverride`;点「自动」恢复随时间切换 - **不串台**:切换壁纸时清空上一张的时段缓存 **🌊 整屏虚化(磨砂)体系** - **统一虚化**:一条滑条控制整屏壁纸模糊度 + 侧边栏/标题栏白雾厚度;聊天区是否跟随、新会话按钮是否跟随各自独立 - **界面虚化(各自独立开关 + 程度)**:对话框(通用居中窗口 + 聊天输入框)、设置面板、下载/确认弹窗、弹层(菜单/下拉/提示)、遮罩(全屏背景)、左侧边栏磨砂 - **透出壁纸**:左侧边栏 / 标题栏 / 右侧边栏 dock 各自独立,标题栏磨砂可单独指定半径 **🎨 主题色与玻璃外观(Aqua 实验默认全关)** - **主题颜色(`themeColor`)**:取色盘 + 预置,驱动侧栏/标题栏/新会话按钮/设置弹窗底色;**配色(`accent`)**驱动品牌交互色(按钮/滑条/选中/链接/发送键) - **面板颜色匹配壁纸(`aquaTint`)**:自动采样壁纸主色(视频/GIF 每 2 秒刷新);**统一雾**(全屏色调雾罩)、**自适应文字色 + 蓝色清理**、**深底文字可读增强**、**任务列表磨砂** - **液态玻璃(CSS/SVG 版)**:`lgCss` + 折射强度,作用于输入框/左侧边栏/标题栏;`lib/liquid-glass/` 的 WebGL 运行时不参与生成(见[文件结构](#文件结构)) **🧩 dsh-better-sidebar 适配(检测到该插件后显示)** - 已安装时「其他」tab 出现**适配分类**:总开关 `bsCompat`(**默认开**)+ `bsFloat`(悬浮双层修复:14px 圆角外壳 + 内层透明 + 零外边距 + resize strip 挪进面板)/ `bsFont` / `bsReveal` + `bsRevealAlpha` / `bsAqua` - 宿主 `/ping` 返回 `{ok, version, betterSidebar, betterSidebarVersion}`;客户端写 `body[data-mpw-bs-version]`,版本专属规则用 `[data-mpw-bs-version^="…"]` 门控(`lib/index.js:1626-1643`、`lib/client.js:255-269`) - 详见 [`docs/BETTER-SIDEBAR-COMPAT.md`](docs/BETTER-SIDEBAR-COMPAT.md)、[`docs/BETTER-SIDEBAR-DOM-CONTRACT-0.19.1.md`](docs/BETTER-SIDEBAR-DOM-CONTRACT-0.19.1.md),回归 `node tools/better-sidebar-compat-test.mjs` **⏯️ 播放控制与省电** - 视频/网页壁纸可**暂停/播放**(设置页「壁纸设置」下的按钮),暂停状态实时反映视频实际状态;**调整无关设置不会触发重播**(`video.src` 判等已修) - **省电三档**:页面隐藏/切页暂停、窗口失焦暂停、电池供电暂停(`getBattery` 缺失则静默跳过);任一档触发即暂停,全部恢复才继续;与手动暂停共用一套门控 **🚀 大文件混合模式(hybrid,默认开)** - mpkg **流式上传**到 DSH 宿主 → 磁盘存储 → HTTP Range 流式播放(`lib/index.js:1688-1728`、`:1730-1790`);**>600MB 也能放**,因为流不进内存;关掉则回纯浏览器模式(600MB 上限) **🖼️ 本地壁纸库与轮换** - Steam 自动发现 + 自定义目录(跨平台目录选择器);WE 原生播放列表(`config.json` 的 `general.playlists`)导入为轮换列表 - 上一个/下一个一键切换、定时自动轮换(`rotate` + `rotateMin`,1–120 分钟);列表勾选后滚动不跳顶 **🛡️ 安全与共存** - **冲突检测**:检测到其他壁纸/主题插件时自动关闭本功能(可手动强开,写 `forceEnabled`) - `.exe/application` 壁纸完全排除(`lib/web-wallpaper.js:101`、`:199`);自定义目录只读媒体文件;宿主路由有路径穿越校验;网页壁纸 iframe 沙箱隔离 **💾 备份与恢复 / 设置持久化** - 「其他」tab 的**备份与恢复**导出外观类设置为可分享 JSON(`BACKUP_FIELDS`,`lib/client.js:11979-11993`),导入即还原 - 设置除浏览器 `localStorage`(键 `dsh.mpkg-wallpaper.v2`,`lib/client.js:48`)外另存宿主端 `~/.dsh-mpkg-wallpaper/settings.json`,换端口/清浏览器数据不丢 ## 支持的壁纸类型与边界 这节回答「我手上的素材能不能用、能用到什么程度」;表后的边界清单说明为什么有些事做不到。 | 类型 | 表现 | 能控制什么 / 做不到什么 | |---|---|---| | **mpkg(视频类)** | ✅ 完整 | 内嵌 mp4/视频纹理直接播放;静音、倍速、暂停、模糊/缩放/亮度全可调 | | **mpkg(场景类)** | 🟡 折中 | 容器素材提取:静态帧 / 图层合成 / 内嵌视频时段;**Live2D 木偶、shader、脚本做不到**(见下) | | **时间变化壁纸** | ✅ 多时段 | 自动切换 + 手动锁定;只提取当前时段 | | **视频(mp4/webm/mov/m4v)** | ✅ 完整 | 直接播放;解码帧率上限/分辨率上限需 ffmpeg 转码 | | **网页(HTML)** | 🟡 实验性 | 沙箱 iframe + WE API shim;**只读设置项的 Live2D 类可改**;外网 SDK / 重交互类未适配 | | **scene.pkg 原始目录** | 🟡 折中 | 同 mpkg 场景类 | | **preview.gif / 图片 / 动图** | ✅ 完整 | 场景壁纸无更多素材时回退作者预览图(`lib/client.js:887`、`:12272`) | | **Application(exe)** | ❌ 排除 | 内容判定即 `unknown/excluded-application`,绝不读取/执行(`lib/web-wallpaper.js:199`) | | **自定义目录(混合)** | ✅ 完整 | mpkg 与 workshop 子目录混放;深度 ≤4、条数 ≤4000 的有界扫描(`lib/web-wallpaper.js:213-232`) | **明确的边界**(都不是"以后再说",是当前实现的事实): - 场景壁纸的**完整动态还原做不到**——MDL 木偶骨架无公开格式文档、shader/脚本无 Web 端运行时(见[场景适配](#场景scene壁纸适配现状)) - **纯 Scene 渲染方式选择器目前未接线**:「其他」tab 的 `sceneRender`(webgl/static/elysia)有按钮、有写入,但全仓没有读取点;实际路径由渲染器可用性决定(在线走 `:8899` iframe,离线回退静态帧,`lib/client.js:3133-3138`) - 网页壁纸的 CSS `:hover/:active`、`isTrusted:true`、帧内 `contextmenu`、指针锁定/全屏/下载弹窗**做不到**(合成事件的固有边界,`docs/WEB-WALLPAPER.md` §11.4) - 超过 600MB 的素材只在 **hybrid 模式**下可用;纯浏览器模式另有 250MB(视频纹理)/200MB(图片)/100MB(本地图片文件)上限 ## 设置项总表(7 个 tab) 这是**全部设置项的权威表**:每行 = 面板文案 + 内部键名 + 默认值 + 作用 + 关闭/回退。tab 顺序与面板一致,固定为 `TAB_ORDER = ["source","wallpaper","appearance","unify","blur","other","liquid"]`(`lib/client.js:10730`),界面文案:**背景来源 / 壁纸设置 / 外观 / 界面统一 / 界面虚化 / 其他 / 测试项**。 ### 1. 背景来源(source) | 面板文案 | 内部键 | 默认 | 作用 | 关闭 / 回退 | |---|---|---|---|---| | 启用壁纸引擎背景功能 | `enabled` | 开 | 总开关;关闭即不应用任何背景 | 关 | | 上传到 dsh 进程流式播放 | `hybrid` | 开 | 大文件混合模式(上传宿主 → 磁盘 → Range 播放,无 600MB 上限) | 关 = 纯浏览器模式 | | mpkg 文件 / 图片 / 视频 / 图片链接 | — | — | 文件选择与 URL 输入(`http(s)` 或 `data:image`) | 「清除壁纸」按钮 | | 自定义目录 | `customDirPath` | 空 | 任意目录;可指 workshop 主目录,每个子文件夹识别为一张壁纸 | 清空输入 | | 本地壁纸库(Steam 扫描) | — | — | 扫描 WE 安装与创意工坊,导入壁纸与 `config.json` 播放列表 | 重新扫描覆盖 | | 轮换(定时自动切换) | `rotate` / `rotateMin` | 关 / 5 分钟 | 到点切换下一个壁纸(1–120 分钟) | 关 | | 时段 | `timeOverride` | 自动 | 手动锁定清晨/白天/黄昏/夜晚;按钮只列容器里真实存在的时段 | 点「自动」 | | 当前壁纸卡片 | — | — | 预览图、显示名、容器内文件名、类型;暂停/播放、刷新、清除 | — | ### 2. 壁纸设置(wallpaper) 含「壁纸画面」与「省电」两个子分组。 | 面板文案 | 内部键 | 默认 | 作用 | 关闭 / 回退 | |---|---|---|---|---| | 静音(网页壁纸) | `mute` | 开 | 网页壁纸音频;关 = 放壁纸声音 | 关 | | **Now playing(左侧栏「设置」上方)** | `npNowPlaying` | **开** | 左侧栏挂可展开播放器(传输行 = 壁纸声音控制);**关掉仍是零注入**;同一位置被别的插件占用时自动让位(`data-mpw-np-yield`) | 关 / 恢复默认 | | 播放/暂停同时控制壁纸 | `npLinkWallpaper` | 开 | Now playing 的播放/暂停与进度同时驱动壁纸自身;关 = 只驱动本插件播放器(壁纸媒体是唯一声源时控件**如实 disabled**) | 关 | | 水平翻转(镜像) | `flipX` | 关 | 壁纸左右镜像 | 关 | | 垂直翻转(镜像) | `flipY` | 关 | 壁纸上下镜像 | 关 | | 解码帧率上限 | `fpsCap` | 无限制 | 源帧率超限时宿主 ffmpeg 抽帧转码(24/30/48/60) | 选「无限制」 | | 分辨率上限 | `resMax` | 原始分辨率 | ffmpeg 缩放(720p/1080p/2K,保持宽高比) | 选「原始分辨率」 | | 视频倍速 | `playbackRate` | 1x | 0.5–2x(档位 0.5/0.75/1/1.25/1.5/2) | 1x | | ffmpeg 状态 | — | — | 显示系统/缓存/环境变量来源;未装可下载,缓存装的可卸载(不动系统) | — | | 可调参数(折叠区) | `propEdits` | 空 | mpkg 只读展示;网页壁纸可改(分辨率/语言/音量等,见下) | 壁纸级重置 | | 磨砂模糊 | `blur` | 12px | 壁纸层模糊(0–40) | 0 | | 镜头缩放 | `zoom` | 100% | 10–2000% | 100% | | 画面亮度 | `brightness` | 100% | 50–150% 滤镜 | 100% | | 镜头位置(平移) | `lensX` / `lensY` | 0 / 0 | 水平/垂直平移,各自 ±2000 | 0 | | 省电·页面隐藏/切页暂停 | `powPauseHidden` | 关 | `visibilitychange` | 关 | | 省电·失焦暂停 | `powPauseBlur` | 关 | `blur/focus` | 关 | | 省电·电池供电暂停 | `powPauseBattery` | 关 | `getBattery`;API 缺失静默跳过 | 关 | ### 3. 外观(appearance) 含「透出壁纸」子分组。 | 面板文案 | 内部键 | 默认 | 作用 | 关闭 / 回退 | |---|---|---|---|---| | 悬浮效果 | `float` | 关 | 左侧边栏/标题栏变悬浮卡片(圆角+阴影+透出) | 关 | | 主题颜色 | `themeColor` | 空 | 侧栏/标题栏/新会话/设置弹窗底色 tint(取色盘 + 预置) | 空 = 不启用 | | 面板颜色匹配壁纸 | `aquaTint` | 关 | 自动采样壁纸主色作面板底色(视频/GIF 每 2s 刷新) | 关 = 用取色盘 | | 配色 | `accent` | 空 | 品牌交互色(按钮/滑条/选中/链接/发送键) | 空 = DSH 默认 | | 遮罩自定义色 | `aquaColor` | 空 | 统一雾/面板的自定义色 | 空 = 灰色 | | 自定义灰字颜色 | `fontColorGray` | 关 | 灰字走自定义色(配 `fontColorGrayColor`) | 关 | | 左侧边栏透出壁纸 | `sidebar` | 开 | 关 = 侧栏纯色不透明 | 关 | | 左侧边栏磨砂 | `sidebarBlur` | 关 | 侧栏自身 `backdrop-filter`;弹窗打开时自动摘除 | 关(需先开侧栏透出) | | 左侧边栏磨砂程度 | `sidebarBlurAmount` | 14px | 0–40;统一虚化开启时被接管 | — | | 标题栏透出壁纸 | `headerBg` | 开 | 关 = 标题栏纯白 | 关 | | 标题栏磨砂 | `headerBlur` | 开 | 统一虚化开启时被接管 | 关 | | 标题栏磨砂程度 | `headerBlurAmount` | 0% | 白雾厚度 0–100%(默认 0 = 透明) | 0 | | 单独调节标题栏磨砂 | `headerFrostOwn` | 关 | 开 = 用 `headerFrostAmount` 覆盖磨砂半径 | 关 | | 标题栏磨砂强度 | `headerFrostAmount` | 30px | 0–60 | 0 | | 右侧边栏/dock 虚化 | `rightSidebarBlur` | 开 | DSH 自带右侧边栏与底部 dock | 关 | | 虚化程度 / 表面透明度 | `rightSidebarBlurAmount` / `rightSidebarAlpha` | 14px / 45% | 0–40 / 0–100% | — | ### 4. 界面统一(unify) | 面板文案 | 内部键 | 默认 | 作用 | 关闭 / 回退 | |---|---|---|---|---| | 统一虚化 | `unifyTint` | 开 | 整屏模糊感由一个条控制;开启后接管侧边栏/标题栏/右栏磨砂 | 关 | | 整屏虚化程度 | `unifyAmount` | 30px | 0–40(控制壁纸层 blur) | — | | 左侧边栏/标题栏透明度 | `sidebarAlpha` | 35% | 白雾厚度 0–100% | — | | 聊天区跟随整屏虚化 | `chatFollow` | 开 | 关 = 聊天区由「磨砂模糊」条控制 | 关 | | 新会话按钮跟随面板不透明度 | `sessionFollow` | 开 | 关 = 回到宿主原色 | 关 | | 统一雾(全屏遮罩) | `aquaMask` | 关 | 所有表面共享一种雾色(原 Aqua 实验项) | 关 | | 统一雾强度 | `aquaMaskAlpha` | 82% | 0–100% | — | ### 5. 界面虚化(blur) | 面板文案 | 内部键 | 默认 | 程度键 / 默认 | 关 | |---|---|---|---|---| | 虚化对话框 | `dialogBlur` | 开 | `dialogAmount` 14px | 关 | | 虚化设置面板 | `settingsBlur` | 开 | `settingsAmount` 14px | 关 | | 虚化下载/确认弹窗 | `confirmBlur` | 开 | `confirmAmount` 12px | 关 | | 虚化弹层 | `popoverBlur` | 开 | `popoverAmount` 10px;另有 `popoverAlpha` 94% 表面不透明度 | 关 | | 虚化遮罩(全屏背景) | `maskBlur` | 开 | `maskAmount` 8px | 关 | ### 6. 其他(other) | 面板文案 | 内部键 | 默认 | 作用 | 关闭 / 回退 | |---|---|---|---|---| | 轻度锐化 | `sharp` | 开 | 提升低清 GIF 观感;卡顿请关 | 关 | | Deep diving 背景方框 | `thinkBg` | 关 | 开 = 思考状态显示模糊背景方框 | 关 | | 任务列表磨砂 | `todoBlur` | 关 | todo 卡片背景模糊 | 关 | | 第三方 UI 圆角兼容 | `roundCompat` | 关 | 兼容第三方插件圆角 | 关 | | 自适应文字色 + 蓝色清理 | `aquaInk` | 关 | 文字色随遮罩亮度自适应 + 品牌色统一(配 `aquaInkColor`) | 关 | | 深底文字可读增强 | `aquaTextEnhance` | 关 | 文字双色描边(近似方案) | 关 | | 纯 Scene 壁纸渲染方式 | `sceneRender` | — | ⚠ 有按钮、有写入,**无读取点**(未接线) | — | | 场景渲染上报(排障) | `sceneReport` | 开 | 壁纸每 10s 把渲染器现场写到 `reports/` | 关 | | 场景首帧看门狗 | `sceneWatchdog` | 开 | 超时未出画自动回退静态帧;等待时长 `sceneWatchdogSecs` 8s(3–30) | 关 | | 重试渲染器 / 渲染器调试参数 / 扩展钩子地址 | `sceneDebugParams` / `sceneExtUrl` | 空 | 白名单透传(`ln/eye/audit/isolate/parallax/…`);扩展钩子按 `extbase` 拼进 iframe | 清空 / 一键清空 | | 一键诊断上报 | — | — | 收集子系统状态 → `POST /diag`;宿主不可用则下载 JSON | — | | 诊断开关速查(渲染器) | — | — | 10 个常用渲染器诊断开关 + 「复制」URL 片段 | — | | better-sidebar 适配 | `bsCompat` / `bsFloat` / `bsFont` / `bsReveal` / `bsRevealAlpha` / `bsAqua` | 开 / 关 / 关 / 关 / 62% / 关 | 见上文;仅在检测到 better-sidebar 时显示 | 总开关关 = 全部不生效 | | 备份与恢复 | — | — | 导出/导入 `BACKUP_FIELDS` 白名单内的设置(不含当前壁纸与扫描目录) | — | | 恢复所有默认设置 / 前往反馈 / 检查更新 | — | — | 重置外观数值;一键更新从 GitHub 拉最新代码 | — | ### 7. 测试项(liquid) | 面板文案 | 内部键 | 默认 | 作用 | 关闭 / 回退 | |---|---|---|---|---| | 测试模式总开关 | `lgTest` | 关 | 只保留壁纸 + 悬浮 + 布局,禁用全部外观类 | 关 | | 液态玻璃(CSS 版) | `lgCss` | 关 | 纯 CSS/SVG 折射 + 高光(不占 WebGL 上下文,可与场景壁纸共存) | 关 / URL `?lgcss=off` | | 折射强度 | `lgCssAmount` | 14px | 0–40(0 = 纯模糊) | — | | 输入框 / 左侧边栏 / 标题栏液态玻璃 | `lgComposer` / `lgSidebar` / `lgHeader` | 关 | 各自选择作用目标(JS 打 `[data-mpw-lg-css]` 标记) | 关 | | 独立演示页(端口 3081) | — | — | `tools/liquid-demo/` 的 WebGL2 演示页(独立服务,不影响插件) | — | ### 没有面板控件的设置键 这些键**存在且参与逻辑**,但设置页里没有对应控件;只能通过备份导入、`localStorage` 手工改写或 URL 参数触达(`lib/client.js:101-232` 是全部默认值,`tools/switch-wiring-test.mjs:41-64` 是「只影响运行时」的白名单与理由)。 | 键 | 默认 | 说明 | |---|---|---| | `clock` / `clock24h` / `clockSec` / `clockDate` / `clockPos` / `clockSize` | 关 / 开 / 关 / 关 / `tr` / 40 | 时钟是**运行时兼容项**:旧配置仍会渲染,设置页已无开关 | | `bsAlpha` | 关 | better-sidebar 面板跟随主题底色;CSS 有读取点,面板无控件 | | `bsBottomAvoid` | 关 | 已定案的**故意空操作**(对齐交给 better-sidebar 自己的 ResizeObserver) | | `newStyle` | 关 | 只改设置页控件外观(JS 选 className),不进 `buildCss` | | `forceEnabled` | 关 | 冲突检测下手动强开的运行时优先级标记 | | `opacity` | 82 | 「面板不透明度」滑条已删除(统一虚化下由 `sidebarAlpha` 取代);值仍被读取(`lib/client.js:5887`、`:5981`) | | `aquaTintStrength` | 45 | 面板取色的壁纸主色混合比例;运行时读取(`lib/client.js:5575`),无控件 | | `glassColor` / `glassAlpha` | 空 / 12 | 早期 WebGL 液态玻璃的遗留键:只随备份导出/导入与「恢复默认」走动,**无控件、无读取点**(`lib/client.js:11968`、`:11986`) | | `webInteraction` | `pointer` | 网页壁纸交互档位(`off`/`pointer`/`full`):**无面板控件**,用 URL `?mpwinteract=…` 或写存档 | | `sceneRendererUrl` | `http://127.0.0.1:8899/` | 场景渲染器地址,可覆盖(`lib/client.js:3129-3132`) | | `npVolume` | 100 | Now playing 卡片里的**音量电平**(0..100,落到真实元素);默认档**从不写元素音量**,只有你动过才写 | | `glassWindow` | — | **已退役删除**(2026-09-19):无控件、无读取点,功能已被 `settingsBlur` + `dialogBlur`/`popoverBlur` 覆盖;源码与 zh/en 字典 0 残留 | ## Now playing 与壁纸声音 这节说明左侧栏那个播放器**挂在哪、显示什么、能控什么**——它控制的是壁纸自己的声音。 > 定位口径:本节按**符号名**引用实现(`lib/now-playing.js` 的 `resolveAnchor` / `shouldHide` / `occupantOf` / `PlayMark` / `markYield`,`lib/now-playing-math.js` 的 `opsX` 等,`lib/client.js` 的 `npResolveMedia` / `npActiveVideo` / `npAudioScope` / `npApplyMute` / `applyNowPlaying`)——**行号会随版本漂移,以符号为准**。形态是「源 + 生成内联」:`lib/now-playing-math.js` + `lib/now-playing.js` 由 `tools/build-now-playing.mjs` 逐字节内联进 `lib/client.js` 的 `MPW-NP-GEN-START/END` 生成区。 - **挂载点**:宿主 slot `sidebar.footer.action`(`lib/client.js` 里 `createSlotAction` 的注册项:`id:"mpw-now-playing"`、`order:60`)。拿不到 slot 时 `resolveAnchor()` 按模式降级:`slot` → `settings-slot`(宿主设置格子之前)→ `settings-area`(`[class*="settingsArea"]` 之前)→ `foot`(`[class*="footArea"]` 首位);一条都不成立就**不建任何节点**并打一行 `console.warn`。**锚点晚出现也照样挂上**:找不到落点时盯住文档,宿主 slot 出口渲染出来后自动补挂(旧写法只 warn 就 `return` ⇒ 真机切壁纸后控件再也不出现)。 - **让位(默认开的配套)**:`occupantOf(container, mode, selfNode)` 逐个看容器子节点,放行三类——我们自己的节点、宿主自有节点(slot 出口 / 设置格子)、实质空节点;剩下第一个即算「占用者」⇒ 不挂(挂载前)或撤下(挂载后,`MutationObserver` 且 `subtree:true`),写 `data-mpw-np-yield="foreign-occupant"` 并打一行可读 warn;占用者走了会自己回来。判据是**双向**的:我们自己的节点与宿主的格子都不许被误判成占用者。 - **左侧栏收起即隐藏**:`data-mpw-np-hidden` + CSS `display:none`。判据以**物理宽度优先**(`shouldHide(width, hostCollapsed)`:量到 ≥ `NP_COLLAPSE_MAX_W = 96` 就不隐藏),宿主信号(slot `wide` / `data-sidebar-collapsed` / 根类名 `collapsed`)只在宽度**量不到**时兜底;锚点搬动后做**一次性**补判。宽度不够时整体按 `--mpw-np-fit = clamp(avail/260, 0.5, 1)` 缩放,`avail` 量的是**我们自己的容器**(不是 `[class*="sidebarCol"]`——真机上同类名不止一处)。 - **形态**:一颗胶囊展开成卡片——封面(当前壁纸缩略图)、标题/副标题、进度条 + 时钟、整块点击热区。**展开态四个键**:上一首 / 播放-暂停 / 下一首 / 静音-取消静音;**收起态三个键**——静音键随卡片出现,因为收起态的传输行是按 `opsX(0) = 206` 的 88px 三键行定位的,硬塞第四键会溢出右边距。展开是自停的 0→1 补间(无常驻 rAF);播放/暂停**不是换图标**,而是那对八点四边形,形状由**播放状态自己的补间**(`mark`:0=暂停 1=播放)驱动,形变进度 `p` 只管尺寸/位置。 - **数据源**(`npResolveMedia`:**只报我们真的知道的东西**): | 当前壁纸 | NP 显示 | 能控什么 | |---|---|---| | 视频壁纸(当前**真的在放**的那个 `