dsh-pet-indesktop 灵动岛功能全指南:5 个内置指标、游戏帧率采集与第三方段接入实战
dsh-pet-indesktop 灵动岛功能全指南:5 个内置指标、游戏帧率采集与第三方段接入实战
dsh-pet-indesktop 是一个支持 Windows、Linux、macOS 的跨平台桌宠项目,屏幕顶部的「灵动岛」胶囊小窗是它最实用的功能之一。本指南讲清楚三件事:段化重设计如何让你同时看到时间、CPU、内存、网络等多段指标,游戏帧率指标如何采集到真实 FPS,以及第三方开发者如何把自己的指标段接上岛。全部指标默认关闭、按需开启、无人看时零开销。
一、灵动岛是什么:从「一个槽」到「一条段序列」
灵动岛是屏幕顶部一条独立胶囊小窗:左侧角色图标 + 名称,中间是信息槽,右侧一个状态圆点。桌宠隐藏后它仍可常驻,展开后还能看到卡片详情。
旧版信息槽只有一个槽位,这是段化重设计要解决的核心痛点:
- 打开「网络」开关后,网络读数会接管整个信息槽,时间直接被吃掉(PR 报告里保留了 before/after 对照);
- 想同时看「时间 + CPU + 内存 + 网络」在结构上就做不到;
- 网络读数每秒变一次,旧架构每秒写一次窗口几何(
setFixedSize),多宠场景下持续抖宽(对照实验里旧实例岛宽在 216→210→207px 之间逐秒跳动)。
段化重设计把信息槽改为一条段序列:
- 主信息段恒在最前:时间 / 余额 / 峰谷 / 自定义文本四选一,不再被任何指标接管;
- 指标段按你勾选的顺序追加:网络、CPU、内存、GPU、游戏帧率,竖线分隔;
- 段数不设上限,胶囊总宽超过「屏宽 − 32px」才触发收缩流水线(见第四节)。
二、5 个内置指标段:各自的数据口径
| 指标段 | 读什么 | 关键口径 |
|---|---|---|
network 网络 |
↓下行 / ↑上行速率 + 延迟 | 5 列定宽槽,速率监测不产生流量,延迟探测每轮约 0.16 KB |
cpu |
CPU 总占用百分比 | 不逐核心;与内存共用一条后台采样线程,1 秒一次 |
mem |
内存占用百分比 | 「已用」口径以系统自身为准 |
gpu |
GPU 最忙引擎占用 | 不是任务管理器的整卡百分比;非 Windows 不占位 |
fps 游戏帧率 |
目标应用真实的 Present 帧率 | 仅 Windows x64,详见第三节 |
实现分别在 pet/island_segments.py(段契约层,零 Qt)、pet/sys_monitor.py(CPU/内存共享采样器)、pet/gpu_monitor.py(GPU 读数器)。
四态语义:没有读数就说没有
所有指标段共用一套「四态」呈现,这是这套设计最被强调的红线——不伪造读数:
| 状态 | 胶囊上显示 | 含义 |
|---|---|---|
ok |
标签 + 真实读数 | 采到了 |
sampling |
标签 + -- |
还没采到第一拍(不是 0) |
error |
标签 + -- |
取值或格式化失败,原因写进展开卡片 |
unsupported |
整段不占位 | 本机没有这项能力(如非 Windows 开 GPU / 帧率) |
-- 占位符与最坏读数样本同盒宽,所以状态切换不会引起岛宽跳动。告警方面,CPU 占 80/92%、内存 85/95% 会分别染 warn/crit 两级告警色,并带 3 个百分点滞回——79/80 来回横跳不会闪色。
三、游戏帧率段:如何采到真实 FPS
「灵动岛指标 · 游戏帧率」读数来自官方 PresentMon 独立采集程序(随 Windows 安装包分发,MIT 许可):它读显卡 Present 事件的 MsBetweenPresents 均值,即游戏每秒真正呈现到屏幕上的帧数。
三个常见误区,口径上都不可混算:它不是桌宠动画的帧率(那是素材与渲染节拍),不是 GPU 占用推算出来的,不是窗口抓取帧数。多个渲染链(swapchain)也不相加——主值只取窗口内仍然存活且最忙的那一条链。
目标模式与 Windows 权限
设置页在游戏帧率开关下多两行:目标模式(跟随前台程序 / 指定程序)与程序名。指定程序只按镜像名匹配、永不执行它;不猜目标,不会替你挑一个「帧率最高的程序」。
权限方面(见 pet/fps_permission.py):采集走系统级性能事件接口,Windows x64 上首次使用可能需要把当前账户加入 Performance Log Users 组,设置页提供一行操作入口并提示重新登录生效;没授权时卡片里写真实原因,绝不用假读数顶替。非 Windows、ARM64 架构上整段按 unsupported 不占位,只在卡片里说明原因。
解析层源码:pet/game_fps.py、pet/island_fps.py。
四、段太宽怎么办:收缩流水线与 +N chip
当胶囊总宽超过「屏宽 − 32px」,收缩流水线逐级降级,取第一个放得下的级别:
- 名字省略(96px → 40px 盒);
- 名字整段隐藏;
- 尾部指标段开始整段折进一个
+Nchip(你island_metrics列表里排后面的段先折,列表序 = 优先级); - 自定义主信息段省略到 96px;
- 保底截断。
两个关键纪律:
- 采样值永不改岛宽:每段的字段盒宽由你声明的最坏样本实测得出,读数只在盒内右对齐伸缩——
9% → 100%个位像素不动,数字跳动不推挤邻居。这条是结构保证,不是口头约定; - 折叠 = 退订:被折进
+N的段即时停止采样(网络整条收口、CPU/内存按段退订),展开后首轮按--恢复;停靠细条态、岛隐藏同样 0 采样器 + 0 定时器 + 0 线程。
布局纯函数层在 pet/island_layout.py(零 Qt,便于逐像素测试),岛本体接线在 pet/dynamic_island.py。
五、视觉与细节:状态点、告警色与四分区卡片
- 状态点五态:错误红点 > 待确认 accent 空心环 > 工作 > 隐藏/离线中性空心环 > 完成绿点(4 秒瞬态回落)> 空闲中性实心;
- 单位弱化双盒:数值盒 13px 右对齐,单位盒 10px 降透明度 70%,一眼扫过去先看数;
- 展开卡片四分区:概览 / 指标详情(每段一行:值、单位全称、来源、N 秒前更新)/ 最近消息 / 操作。
unsupported段在胶囊上零占位,但卡片里会写明「为什么不可用」。
P2 视觉打磨的完整记录见 PR-REPORT-ISLAND-P2P3-VISUAL-EXTENSION-2026-10-07.md。
六、第三方指标段接入:只交数据,拿不到画笔
如果你想让自己的传感器读数(CPU 温度、机箱风扇、NAS 负载……)上岛,官方扩展契约只有一个原则:第三方只交数据与声明,怎么画、画多宽、折谁,全是宿主的事——你拿不到 QPainter,契约层 pet/island_segments.py 不 import 任何 Qt。
两条接入路线
路线 A(进程内):第三方库直接调用注册接口:
from pet import island_segments as segments
segments.register_segment(
id="cpu_temp", # 必填:稳定标识,无空白,≤32 字符
label="温度", # 可选:≤6 字符
format_value=fmt, # 必填:裸值 -> 文案
max_text="88", # 必填:最坏读数样本
unit="°C",
thresholds=(70.0, 85.0),
read=read_celsius,
)
路线 B(组件目录,推荐):在可信本地目录放一个组件子目录,声明写 JSON 清单:
%APPDATA%/dsh-pet-standalone/island-extensions/你的组件/
island-component.json # 静态声明(id / label / max_text / thresholds / provider 文件名)
provider.py # 运行期才导入:read() 取值、format_value() 格式化
组件宿主实现在 pet/island_extension_host.py,完整契约(含可原样跑通的示例、护栏与红线)见官方文档 ISLAND-SEGMENTS-EXTENSION.md。
三条必须知道的规则
max_text必填,宁拒注不跳宽:盒宽靠它实测,缺了直接注册失败——「岛宽跟着读数跳」是红线;- 四道失控护栏:格式化抛异常 → 段降级
error;返回巨型串 → 度量前截断 32 字符;返回多行 → 压平单行;注册期非法 id / 重复 id / 阈值倒挂 → 直接拒注。任意一条触发后,整岛宽度与其余段位置一个像素都不变; - 超宽不拒收:声明盒宽 > 120px 的段照常注册,但会进入收缩流水线「+N 首批折叠候选」——中间段的超宽段也会先于尾部段被折,长段自付先折的代价。
采样纪律与安全边界
- 装 1 个还是 20 个组件,只有一条有界节拍的后台采样线程;宿主 GUI 只读快照,你的
read慢不会卡界面; - 0 订阅 = 零开销;慢读连续 2 次即熔断该段(此后不再调它,卡片写原因),重新订阅视为新序列;
- 配置准入 = 内置段 ∪ 清单组件,与「进程里谁注册过」无关,独立设置进程保存配置不会误清你的偏好;
- 它不是沙箱:组件是本机可信代码,在本进程里执行,防的是「坏读数 / 慢读拖垮界面」,不隔离恶意插件;宿主不下载、不远程执行、不扫可信目录之外的目录。
七、开启步骤与开销速览
开启指标(1 分钟上手)
- 打开设置页「桌面组件」小节,确认「启用灵动岛」「显示信息槽」已开;
- 在「灵动岛指标 ·」行勾选需要的段(搜索框输入「CPU」「内存」「帧数」也能直接命中);
- 游戏帧率按需再设「目标模式」与「程序名」,首次使用按提示授予 Windows 权限;
- 保存立即生效(写回即刷新)。旧版「网络接管信息槽」开关会自动迁移为
island_metrics列表成员,无需手动处理。
开销速览(项目实测口径)
| 场景 | 开销 |
|---|---|
| 稳态采样 tick(每秒) | 行计划缓存命中约 47µs,0 次窗口几何写入(旧架构每秒 1 次,已消除) |
| 行计划重算 | 约 434µs,仅在结构变化时触发(时间跳分钟 / 配置改动 / 换屏) |
| 指标关闭 / 段被折进 +N / 停靠细条 | 0 采样器 + 0 定时器 + 0 线程 |
| 游戏帧率采集 | 开启且存在目标才启动随包采集程序;Windows 包体积 +约 0.94 MiB |
| 第三方组件 | 全部共享同一条后台采样线程,0 订阅零调用 |
八、小结与源码导航
| 想做什么 | 去哪里 |
|---|---|
| 改主岛渲染 / 段序列组装 | pet/dynamic_island.py |
| 读段契约(四态 / 字段盒 / 告警判定) | pet/island_segments.py |
| 读收缩流水线纯布局层 | pet/island_layout.py |
| 游戏帧率解析与命令行 | pet/game_fps.py、pet/island_fps.py |
| 第三方组件宿主与采样线程 | pet/island_extension_host.py |
| Windows 帧率权限 | pet/fps_permission.py |
| 设置页五个指标开关行 | pet/settings_network.py |
| 设计背景(P1 / P2-P3) | P1 段化重设计报告、P2P3 视觉与扩展报告、游戏帧率 PR 报告 |
三句话总结:段化让你想看几个指标就摆几个;收缩流水线保证再挤也不乱;四态语义保证没数就写 --,绝不伪造。想扩展的读者,从 max_text 必填和两条接入路线开始读 ISLAND-SEGMENTS-EXTENSION.md 即可上手。


