dsh-occlusion-throttle:窗口被完全遮挡时暂停 DSH 桌面端动画渲染

前言

DeepSeek Harness(DSH)桌面端基于 Electron / Chromium。实测表明:只要窗口没有最小化,渲染进程里常驻的 requestAnimationFrame(rAF)循环仍会按约 60 fps 出帧,即便窗口已经被别的程序完全盖住。Chromium 自带的遮挡检测对「普通窗口叠在上面」往往有效,但对独占全屏游戏这类绕过 DWM 的遮挡识别不到,GPU 与渲染进程仍会维持高占用。

最小化可以立刻把占用压到接近零,但会改变窗口状态。维护者 codelearnerlu 的客户端插件 dsh-occlusion-throttle 换了一条路:在宿主侧用 Win32 判断窗口是否被完全遮挡,在前端把 rAF 与 CSS 动画挂起;重新可见时立即恢复。插件归类为「客户端」,仅支持 Windows;当前版本 0.1.0,许可证 MIT,依赖 DSH engines.dsh: ^0.2.1-rc.2。仓库尚未发布到 npm,也未提交 DSH 市场,需按 README 手动链入 desktop profile。

这是什么

dsh-occlusion-throttle 是 DSH 桌面端插件:当应用窗口被其他窗口完全遮挡(典型场景是独占全屏游戏盖住 DSH),暂停动画渲染(rAF + CSS 动画);窗口重新露出时立刻恢复。观察器自身开销约 0.12% 单核(默认 occlusion-watcher.exe),工作集约 15.7 MB。

  • 维护者:codelearnerlu
  • 目录页:https://www.skillhub.cn/plugins/codelearnerlu/dsh-occlusion-throttle
  • 源码:https://github.com/codelearnerlu/dsh-occlusion-throttle

为什么需要它

README 中记录了本机 2026-11-05/06 的对比(页面含常驻 rAF 时):

状态 渲染进程 GPU 进程 帧提交
窗口可见(哪怕无焦点) 65–100% 单核 50–90% 单核 约 6.8–9 MB/s
被全屏游戏完全盖住 仍约 100% 单核 仍约 97% 仍约 8.6 MB/s
最小化 0% 0% 0

结论:未最小化时 Chromium 会持续出帧;独占全屏遮挡需自行判断。本插件在遮挡且文档无焦点时挂起前端动画,目标效果接近「不停渲染却不改最小化状态」。

核心功能与工作方式

检测与通信

  1. 宿主侧(index.js)拉起常驻观察器:默认每 400 ms 用 WindowFromPoint 在窗口内采样 16 个点(中心点快路径);状态变化或每 2.5 s 心跳时输出 JSON。
  2. 暴露本机 HTTP 接口:GET /dsh-occlusion-throttle/state。
  3. 前端(client.js)约每秒轮询一次;当 occluded: true 且 document.hasFocus() === false 时挂起 rAF,并为 <html> 加上 .dsh-occlusion-sleep 以暂停 CSS 动画。
  4. 恢复可见、获得焦点、pointerdown、visibilitychange 或出错路径会立即唤醒并补跑挂起的回调。

安全策略(失败即不降频)

  • 接口 404、超时 800 ms、JSON 解析失败、宿主未就绪:一律按「不遮挡」,正常渲染。
  • 宿主观察器崩溃约 5 秒后自动重启;状态超过 8 秒无心跳按「未知 = 不降频」。
  • 对点穿/透明覆盖层与 DWM cloaked 窗口有过滤,降低误判(例如 NVIDIA Overlay 类 layered 窗口)。

设置界面

设置 →「遮挡降频」:可查看实时状态、启用开关、轮询间隔与最近事件(暂停/恢复时间与累计统计)。

安装与启用

安装需编辑 desktop profile 并重启 DSH(三步)。将 $src 换成你本地的插件目录路径(README 以目录联接为例,不是 dsh plugin add 一键命令):

$profile = "$env:USERPROFILE\.dsh\profiles\desktop"
$src     = "<你的路径>\dsh-occlusion-throttle"
cmd /c mklink /J "$profile\node_modules\dsh-occlusion-throttle" $src

编辑 $profile\package.json:

  1. 在 dependencies 增加一行,例如:"dsh-occlusion-throttle": "link:D:/Study/DeepSeek Harness Workspace/dsh-occlusion-throttle",(路径改为你本机实际路径)。
  2. 在 dsh.profile.bundles 数组增加 "dsh-occlusion-throttle"。

托盘退出 DSH 后重新打开以使 bundle 生效。

验证与典型用法

遮挡时主界面被盖住,无法直接看面板,可用以下任一方式验证。

看日志(推荐)——在另一窗口或第二块屏执行:

Get-Content "$env:USERPROFILE\.dsh\occlusion-throttle.log" -Wait -Tail 5

将 DSH 窗口完全盖住约 3 秒再放开,日志中应出现 client sleep (occluded) / client wake。任务管理器中 DeepSeek Harness (renderer) 在遮挡期间应接近 0 占用。

设置页回放——设置 → 遮挡降频 →「最近事件」与「累计暂停 X 秒 · N 次暂停」。

命令行查状态——端口随启动变化,使用 GUI 中显示的地址:

curl.exe -s http://127.0.0.1:<端口>/dsh-occlusion-throttle/state

前端调试对象:window.__DSH_OCCLUSION_THROTTLE__(含 stats、poll、wakeNow)。

不安装 DSH 也可跑仓库自检(使用 DSH 自带 node):

$node = "$env:USERPROFILE\.dsh\dsh-runtimes\dsh-primary-runtime\dependencies\node\bin\node.exe"
& $node .\selftest.mjs
& $node .\client-selftest.mjs

卸载

  1. 从 package.json 的 dependencies 与 dsh.profile.bundles 删除对应项;
  2. 删除 node_modules\dsh-occlusion-throttle 目录联接;
  3. 重启 DSH。

适用场景与注意

适合谁

  • 常在 Windows 上开着 DSH,同时玩独占全屏游戏或其它全屏程序,希望后台不把渲染/GPU 顶满的用户。
  • 需要在本机 localhost 读状态、并接受插件以当前 DSH 进程权限运行(观察器只读窗口几何,与 127.0.0.1 通信,README 声明不上传数据、不联网)。

边界

  • 仅 Windows(os: ["win32"]);其它平台宿主 no-op。
  • 整窗被遮挡才降频;任一样本点仍露出则视为可见。
  • 暂停的是 rAF 与 CSS 动画,不等价于 Chromium 进程级休眠;与最小化、普通窗口遮挡(Chromium 已能识别)相比,价值主要集中在独占全屏遮挡场景。
  • 安装前请阅读源码与 MIT 许可证;仓库说明当前未上架 npm / 市场,自行链入即表示接受本地构建与观察器(可选本地用 csc 编译 occlusion-watcher.exe,否则回退 PowerShell 版,开销更高)。

DSH 生态强调「一切皆插件」;社区目录站点(如 skillhub.cn)与 DeepSeek / 幻方无官方从属关系,本文档以 GitHub README 与 package.json 为准。

结尾

dsh-occlusion-throttle 用 Win32 点位采样补足 Chromium 对独占全屏遮挡的盲区,以约 0.12% 单核成本在前端闸断动画循环,重新可见即恢复。需要链接安装、重启与日志/设置页验证时,可按上文步骤操作。

  • 插件目录:https://www.skillhub.cn/plugins/codelearnerlu/dsh-occlusion-throttle
  • GitHub:https://github.com/codelearnerlu/dsh-occlusion-throttle
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye