- 桌面应用
【免费下载链接】Lunar
Intelligent adaptive brightness for your external monitors
这篇技术指南围绕 Lunar 6.6.2b5(beta 5)的核心更新展开,重点讲解 Lunar 如何为「硬件上支持、但默认无法开箱即用」的外部显示器强制启用 Night Shift(原彩夜览)与 True Tone(原彩显示),并修复 2023 款 M2 MacBook Air 15 英寸等机型上亮度观测失效的问题。读完本文,你将理解该功能在源码层面的实现链路(DisplayRowView→ 私有 CoreBrightness 客户端 → macOS 显示模式覆盖),掌握其适用前提(Apple Silicon、非内置屏、TV 模式/已覆盖状态),并能结合相关源码文件继续深入排查同类显示器适配问题。
beta 5 更新一览
Lunar 6.6.2b5 是 6.6.2 系列的第 5 个 beta,改动集中在两点:
- Features:为支持 Night Shift 与 True Tone、但开箱即用无效的外部显示器,新增「强制启用」能力;
- Fixes:修复 2023 款 M2 MacBook Air 15 英寸上「观测亮度(observing brightness)」等特定功能失效的问题。
其中「强制启用 Night Shift 与 True Tone」在紧随其后的正式版 ReleaseNotes/6.6.2.md 中同样被列为头号 Feature,属于该版本的核心卖点;同时 6.6.2 正式版还沿用了「Auto Blackout 更多边界场景」「CLI 监听器随 socket 关闭而停止」等改进,以及延迟唤醒后部分动作以规避系统卡死等修复。而本 beta 相关的两项改动在仓库源码中均有明确的实现落点,下面逐一展开。
功能背景:为什么外部显示器开箱即用不了 Night Shift / True Tone
macOS 对 Night Shift(蓝光减弱)与 True Tone(屏幕色温随环境光自适应)的支持,通常以内置屏幕和经苹果认证的显示器为优先。当外接显示器满足以下条件时,Lunar 才有机会介入:
- 显示器硬件层面支持这两项色彩调节能力,但系统层面没有将其暴露为可用状态;
- 显示器被 macOS 识别为 TV 模式(
isTV),或已经被 Lunar 施加过覆盖(override)。
从 Lunar/SwiftUIViews/DisplayRowView.swift 的入口判断可以确认这一点:上下文菜单中「Force enable Night Shift and True Tone」开关仅在Apple Silicon(arch(arm64))下、且「非内置屏(!display.isBuiltin)同时满足display.panel?.isTV == true或已处于覆盖状态(isOverridden)」时才出现。也就是说,这一功能本质上是把系统「藏着」的色彩能力通过底层覆盖的方式重新打开,而不是对任意显示器无脑生效。
强制启用功能的完整实现链路
1. 菜单开关:nightShiftOverrideBinding
功能入口位于显示行视图的上下文菜单(右键显示器名称弹出):
var nightShiftOverrideBinding: Binding<Bool> { Binding( get: { isOverridden(displayID: display.id) }, set: { overriden in let result = if overriden { disableTVMode(displayID: display.id) } else { resetOverride(displayID: display.id) } switch result { case .needsRestart: notify(identifier: "restart", title: "Restart needed", body: "The override will take effect after a system restart.") case .success: break case .error: notify(identifier: "error", title: "Override error", body: "An error occurred while trying to override Night Shift and True Tone.") } } ) }(来源:Lunar/SwiftUIViews/DisplayRowView.swift)
关键行为:
- 开关的「开」状态由
isOverridden(displayID:)决定,即是否已施加覆盖; - 勾选时调用
disableTVMode(displayID:)——把显示器从 TV 模式切换到普通显示器模式,从而让 Night Shift / True Tone 不再被系统屏蔽; - 取消勾选时调用
resetOverride(displayID:)恢复原状; - 三种返回结果分别对应:需要重启生效(
.needsRestart,会弹出系统通知)、立即成功(.success)、失败(.error,弹出覆盖失败通知)。needsRestart的存在说明部分显示器的模式切换必须等待系统重启才能真正生效,这也是该功能「强制」二字的代价所在。
2. 底层实现:私有 CoreBrightness 客户端
Lunar 没有自己实现色温调节,而是通过macOS 私有框架 CoreBrightness提供的两个客户端与系统交互,头文件声明在仓库中:
- Lunar/Headers/CBBlueLightClient.h:管理 Night Shift。以
Time { hour, minute }、CBSchedule { fromTime, toTime }、Status { active, enabled, sunSchedulePermitted, mode, schedule, disableFlags, available }等结构体建模状态,提供setStrength:commit:、setEnabled:、setMode:、setSchedule:、getBlueLightStatus:等方法,并通过supportsBlueLightReduction类方法判断系统是否支持蓝光减弱; - Lunar/Headers/CBTrueToneClient.h:管理 True Tone,接口极简——
available、supported、enabled、setEnabled:四个方法即可完成查询与启停。
注意 Lunar/DDC/Lunar-Bridging-Header.h 中CBBlueLightClient.h处于启用状态、CBTrueToneClient.h被注释掉,说明当前构建中 Night Shift 走的是私有客户端调用,而 True Tone 的强制启用更多依赖上文所述的显示模式覆盖(disableTVMode/resetOverride)来解锁系统能力。
3. 调度与状态机:NightShift封装
在 Lunar/Control/GammaControl.swift 中,NightShift枚举把私有客户端封装成一组易用的静态属性,构成完整的调度状态机:
strength(色温强度):读写client.setStrength(_:commit:)/getStrength(_:),取值 0.0~1.0;mode(调度模式):0 = off、1 = solar(跟随日出日落)、2 = custom(自定义时间段);schedule:NightShiftScheduleType枚举(Lunar/Control/GammaControl.swift),映射为三种模式;自定义模式通过CBSchedule结构体写入fromTime/toTime;isEnabled/isSupported:分别对应setEnabled:与supportsBlueLightReduction();scheduledState:计算「此刻是否处于调度开启时段」,对 solar 模式还会调用BrightnessSystemClient读取sunrise/sunset判断昼夜;enable(mode:strength:)/disable()/previewStrength(_:):其中previewStrength以commit: false预览色温而不落盘,适合拖动滑块实时预览。
一个有意思的细节:enable()在scheduledState为真时会「先存调度 → 置 off → 再写回调度」,利用写入副作用强制刷新一次系统状态,确保调度立即生效(Lunar/Control/GammaControl.swift)。
4. 与 f.lux 的冲突协调
由于 Night Shift 与 f.lux 都依赖同样的 Gamma 手段改变屏幕色温,Lunar 在检测到 f.lux 运行时会弹窗让用户二选一。若用户选择「退出 f.lux 改用 Night Shift」,源码会依次执行:终止 f.lux →NightShift.enable(mode: 1, strength: 1.0)以太阳调度、满强度启用 → 打开系统显示器设置或「显示」偏好面板定位到 Night Shift 页(macOS 13+ 用x-apple.systempreferences:com.apple.Displays-Settings.extension?nightShiftSection,旧版本则执行 AppleScript 点击对应 Tab)(Lunar/Control/GammaControl.swift)。此外 Lunar/SwiftUIViews/HDRSettingsView.swift 提供了「切换 XDR 时禁用 Night Shift 与 f.lux」的开关(对应偏好键disableNightShiftXDR,见 Lunar/Data/DataStore.swift),避免开启 XDR 高亮时与色温调节互相打架。
修复项解析:2023 M2 MacBook Air 15 英寸的亮度观测
beta 5 的另一项改动是修复「2023 M2 MacBook Air 15 英寸上诸如亮度观测等特定功能失效」。虽然该机型未在仓库中出现直接硬编码,但从代码结构可以推断出修复的路径:
- 亮度「观测」依赖对显示设备的动态检测与轮询。Lunar 通过
DisplayServicesHasAmbientLightCompensation(id)判断显示器是否支持环境光自适应(见 Lunar/Data/Display.swift),而内置屏在多数机型上具备该能力,从而可作为自适应亮度的数据源; - 同步模式(Sync Mode)下,Lunar 优先选择「具备环境光自适应能力」的外置屏或内置屏作为亮度信号源(Lunar/Utils/DisplayController.swift 附近的选择逻辑);
- 新机型(M2 世代)的显示服务 API 行为存在差异,导致这些检测在旧逻辑下返回异常。6.6.2b5 的修复正是针对此类机型兼容性的调整——这类修复通常体现在对
DisplayServices*调用结果的处理分支上,建议阅读 Lunar/Data/Display.swift 中hasAmbientLightAdaptiveBrightness、brightnessReadWorks等属性的定义继续追踪。
需要强调的是,仓库中未包含针对该机型专门的兼容代码段,因此「具体修复方式」只能由版本日志佐证其存在,具体分支逻辑以实际运行行为为准。
使用方式与适用前提
操作路径
- 打开 Lunar,点击显示器名称(或快速操作区域的名称文本)弹出上下文菜单;
- 在 Apple Silicon + 外接显示器满足条件时,勾选Force enable Night Shift and True Tone;
- 若提示 "Restart needed",重启系统后生效;若提示 "Override error",则该显示器暂不支持强制覆盖。
生效前提(源码可验证)
| 条件 | 说明 | 源码位置 |
|---|---|---|
| 芯片架构 | 仅 Apple Silicon(arch(arm64)) | Lunar/SwiftUIViews/DisplayRowView.swift |
| 显示器类型 | 非内置屏(!display.isBuiltin) | Lunar/SwiftUIViews/DisplayRowView.swift |
| 覆盖前提 | TV 模式(panel.isTV)或已处于覆盖状态 | 同上 |
| 系统能力 | Night Shift 需CBBlueLightClient.supportsBlueLightReduction()返回真 | Lunar/Control/GammaControl.swift |
相关设置项
- 上下文菜单同时提供System Adaptive Brightness开关与Force keep System Adaptive Brightness disabled开关,均以
hasAmbientLightAdaptiveBrightness为前提(Lunar/SwiftUIViews/DisplayRowView.swift); - 若 Night Shift 调度异常,可在 Lunar 内直接读写调度模式(off / solar / custom),对应
NightShift.schedule的三种取值(Lunar/Control/GammaControl.swift)。
版本演进脉络
- 6.6.0:引入 Preset unlocking,允许在参考预设(reference preset)下解锁 macOS 锁定的Brightness Control、Adaptive Brightness、Night Shift、True Tone等能力(见 ReleaseNotes/6.6.0.md),为「解锁系统隐藏色彩能力」打下基础;
- 6.6.2b5 / 6.6.2:把上述解锁能力进一步推广为面向外部显示器的「强制启用」,并加入 f.lux 冲突协调、
disableNightShiftXDR设置等配套逻辑; - 6.6.2 正式版还在本 beta 基础上修复了键盘背光误开、Intel 机型 Blackout 间歇性退出、Pro Display XDR 上 Full Range XDR 不可用等问题,感兴趣可对比阅读 ReleaseNotes/6.6.2.md。
总结
6.6.2b5 的核心价值在于:把 macOS 私有框架的能力以受控方式暴露给用户,让「硬件支持却用不了」的外接显示器也能享受 Night Shift 与 True Tone。实现上,Lunar 以DisplayRowView上下文菜单为入口,经disableTVMode/resetOverride完成显示模式覆盖,配合CBBlueLightClient/CBTrueToneClient私有客户端完成色彩调节,并通过NightShift封装提供完整的调度状态机;同时针对 2023 M2 MacBook Air 15 英寸等新机型修复了亮度观测兼容性。如果你正在排查自家外接显示器的色温功能不可用问题,建议从 Lunar/SwiftUIViews/DisplayRowView.swift 的入口条件与 Lunar/Headers/CBBlueLightClient.h 的客户端接口开始阅读。
- 桌面应用
【免费下载链接】Lunar
Intelligent adaptive brightness for your external monitors
相关推荐
Taste-Skill 的 3 个旋钮如何快速把 AI 前端从模板脸拉回设计感
Taste Skill 的 3 个旋钮如何快速把 AI 前端从模板脸拉回设计感 你大概也遇到过:让 AI 写个落地页,出来的是同样的紫色渐变、三张等大特性卡、居
AI 技能前端人工智能AI 评测Lunar:为macOS外接显示器打造的智能亮度控制神器
Lunar:为macOS外接显示器打造的智能亮度控制神器 在当今多显示器工作环境中,macOS用户常常面临一个痛点:系统原生功能无法精细控制外接显示器的亮度。L
桌面应用GoAlert配置详解:如何集成GitHub、Slack和Twilio
GoAlert配置详解:如何集成GitHub、Slack和Twilio GoAlert是一款强大的开源值班调度、自动升级和通知系统,确保您永远不会错过关键警报。
后端即时通讯
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考