Article Cover Image

起因

我的 Mac mini M4 基本不关机,平时跑着远程桌面和几个自动化任务,接了三块屏(都是便宜低端的屏幕,贫穷……):

  • 主屏是飞利浦 Evnia 27M2N3800F,27 英寸 4K,跑 144Hz,用 USB-C 转 DP 线连接;
  • 竖着放的是技嘉 G24F,24 英寸 1080p,跑 170Hz,接 Mac 的 HDMI 口;
  • 一个 JetKVM,用来常驻,但只应急远程看画面。

问题是:人不在的时候,屏幕没必要亮着;可要是让整台 Mac 睡眠,远程和后台任务就断了,不睡眠的问题好解决,可以使用系统开关,显示器有时晚上不想在卧室亮着,也懒得关,偶尔还会触发一些bug,所以就试试和克老师写一个,发现用的频率非常高,所以分享给大家。

思路

显示器基本都支持 DDC/CI,可以通过视频线给它发命令,比如调亮度、切换输入源、待机。所以思路是:Mac 本身不动,只让显示器自己进入待机。 这样 macOS 仍然认为屏幕在线,窗口不会乱跑,回来唤醒时,布局也和离开时一样。

我把它做成了几个「档位」:

档位做什么
away通过 DDC 让显示器待机熄屏,Mac 和显示布局都不动
home唤醒显示器,恢复分辨率、刷新率、竖屏旋转
mirror所有屏幕镜像成一块 1080p 桌面,方便远程操作

手机上触发的方式:Mac 上跑一个小 HTTP 服务,只监听 Tailscale 内网地址,请求要带 token 才能执行。iPhone 快捷指令里每个档位做成一个按钮,出门点 away,快到家时点 home。

踩过的坑

  • 关屏不要用「停用显示器」。 我一开始是用 displayplacer 的 enabled:false 关屏的。有一次 KVM 重新插拔后,WindowServer 直接把被停用的两块屏丢掉了,只有重启才能恢复。改成 DDC 待机以后,就再也没出过这种问题。
  • DDC 要直连。 Mac 自带的 HDMI 口和 USB-C 转 DP 线都可以,经过扩展坞基本都不行。
  • 显示器的 UUID 重启后会变。 所以工具每次运行都按显示器名称重新查找。
  • 技嘉 G24F 接 HDMI 时,待机后不响应开机命令(VCP 0xD6),但切换输入源(VCP 0x60)能叫醒它。 所以配置里可以给每台显示器单独设一个「唤醒用的输入源」。
  • Mac mini M4 的显示引擎是有限的。 飞利浦主屏开了 160Hz 超频以后,内核日志出现 no available UFP,第三块屏怎么都点不亮。原因是 4K 高刷屏走 DSC 时,会一个人占两个引擎。在显示器菜单里关掉超频,再按「先插 USB-C,最后插 HDMI」的顺序重插,三块屏就都恢复了。
  • 主屏走 HDMI 2.1 跑 4K@144 时,我遇到过屏幕自己黑一下又亮。 内核日志里有大量 FRL 链路错误。换成 USB-C 转 DP 线以后就没再出现。

开源

我把它整理成了一个通用的小工具,配置写在 JSON 里,list 命令可以列出你自己的屏幕编号:

https://github.com/StevenZFZ/mac-display-profiles

它依赖 m1ddc 和 displayplacer,都可以用 Homebrew 安装。目前只在我这一套设备上验证过(Mac mini M4 + 飞利浦 27M2N3800F + 技嘉 G24F),欢迎反馈你的显示器型号能不能用,感觉这个场景在某些情况下还是有需要的。