DISPLAYDJ / 工程实践 ·
显示器控制,
如何做到可验证?
调一个亮度值很简单。难的是确认操作落在正确的屏幕上、真正生效,并在用户重新接管时及时让路。DisplayDJ 把这些要求放进了菜单栏、独立 CLI 和可选本地服务。
本文依据 v1.0.1 的公开文档与发布记录整理。它说明设计和已记录的验证范围,不是新一轮硬件测试,也不提供未经测量的效率数据。
从桌面里的具体操作开始
外接显示器的日常使用不只有调亮度。有时需要换一个显示模式,有时希望暂时把一块屏幕移出 Mac 桌面,让窗口回到其余屏幕上。DisplayDJ 的断开与重连处理的是桌面拓扑;它不等于把亮度调成零,也不等于切换显示器的输入源。
菜单栏适合直接操作,display-cli 适合脚本和自动化。普通 CLI 不要求打开 App 或启动后台服务;只有需要 HTTP、持续 Gamma 调光或跨命令会话时才使用本地服务。这样的划分让一次查询不必附带一个常驻进程。
一次操作,要把结果带回来
- 识别目标用稳定的显示器身份选择目标,不靠两份枚举列表的下标碰运气。
- 读取基线写入前读取实际值,保留有效的恢复信息,并通过跨进程锁协调操作。
- 执行并回读独立检查结果,不能把请求值原样返回就当作成功。
- 报告或恢复失败时报告具体结果并尝试恢复;离线或恢复失败的记录不能直接丢弃。
断开显示器还有单独的约束:一次只操作一个稳定目标,拒绝镜像集合和最后一块在线屏幕,并保留重连记录。这些保护降低误操作风险,但私有 macOS API 和 DDC 仍可能随系统、设备及连接方式变化。
手动调节之后,自动化应该让路
自动化可能在任务开始时调暗显示器,并计划在结束后恢复。若用户中途通过 DisplayDJ 手动调亮,旧任务结束时再恢复旧值,就会覆盖用户刚做的决定。
v1.0.1 为每块屏幕记录控制权。手动接管后,已有 Agent 会话跳过该屏后续阶段、结束和超时的亮度写入;其他屏幕仍按各自配置处理。新的会话可以从当前值重新建立恢复点。
这个规则覆盖 DisplayDJ 自己的 App、CLI、HTTP、预设及 Gamma 入口。系统设置、显示器实体按键和其他应用的亮度修改,目前不能触发同样的接管检测。App、CLI 和服务也必须使用匹配的版本及状态目录。
先从只读查询开始
下载当前 Apple Silicon ZIP 或 DMG,将 App 放到 /Applications 后,可以直接运行包内 CLI,查看当前环境和显示器:
/Applications/DisplayDJ.app/Contents/MacOS/display-cli doctor --json
/Applications/DisplayDJ.app/Contents/MacOS/display-cli displays --json
这两个示例用于诊断与发现,不请求调节亮度或断开屏幕。后续操作请根据实际枚举结果选定目标,并阅读中文使用说明中的能力与限制。
验证记录能支持哪些结论
| 记录 | 能够说明的范围 |
|---|---|
| v1.0.1:651 项自动测试 | 覆盖规则与模块交互;不等于所有显示器兼容。 |
| v1.0.1:本机内建屏验收 | 记录了手动接管、后续阶段跳过、结束/退出保留手动值和显式撤销;原始亮度恢复后独立回读一致。 |
| v1.0.0:历史外屏验收 | 一条 HP D27k 连接的 DDC 亮度/对比度,以及一条 Dell 连接的断开/重连;不能推广到其他连接。 |
| 仍未覆盖 | Intel、最低系统安装、全部外屏、真实睡眠唤醒与干净用户升级;v1.0.1 未新增外屏 DDC 实写或完整 GUI 人工验收。 |
当前发行物是 arm64、ad-hoc 签名,尚未进行 Developer ID 签名或 Apple 公证。最低部署目标为 macOS 13,不代表已经在 macOS 13 完成验收。恢复也不是绝对保证:强制终止、硬件失联或 API 阻塞都可能影响清理过程。
可以复用的设计经验
把“发出了命令”“独立确认了结果”“在特定环境验收过”分开表达,让接口使用者知道自己拿到哪一种证据。自动化还要显式处理控制权:保存过旧状态,不代表永远有权覆盖当前状态。
DisplayDJ 的实现保留了来自 MonitorControl 等上游的来源与许可说明。这篇案例关注当前项目的接口、协调与验证设计,不将整个硬件底层表述为从零原创。