☰
Lunar 6.6.2b5 详解:为外部显示器强制启用 Night Shift 与 True Tone 的实现原理
2026/10/16 1:53:39 网站建设 项目流程
  • 桌面应用

【免费下载链接】Lunar

Intelligent adaptive brightness for your external monitors

项目地址:https://gitcode.com/gh_mirrors/lu/Lunar
点击查看免费下载

这篇技术指南围绕 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等属性的定义继续追踪。

需要强调的是,仓库中未包含针对该机型专门的兼容代码段,因此「具体修复方式」只能由版本日志佐证其存在,具体分支逻辑以实际运行行为为准。

使用方式与适用前提

操作路径

  1. 打开 Lunar,点击显示器名称(或快速操作区域的名称文本)弹出上下文菜单;
  2. 在 Apple Silicon + 外接显示器满足条件时,勾选Force enable Night Shift and True Tone;
  3. 若提示 "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

项目地址:https://gitcode.com/gh_mirrors/lu/Lunar
点击查看免费下载

相关推荐

上一篇:PhotoDemon:22MB便携式照片编辑器的三大颠覆性应用场景
下一篇:告别Windows USB弹出烦恼:3分钟掌握终极安全移除技巧

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询