diff --git a/DynamicIsland/helpers/CoreBrightnessDisplayClient.swift b/DynamicIsland/helpers/CoreBrightnessDisplayClient.swift
new file mode 100644
index 0000000..a6e2032
--- /dev/null
+++ b/DynamicIsland/helpers/CoreBrightnessDisplayClient.swift
@@ -0,0 +1,82 @@
+/*
+ * Atoll (DynamicIsland)
+ * Copyright (C) 2024-2026 Atoll Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+import Foundation
+import ObjectiveC.runtime
+
+final class CoreBrightnessDisplayClient {
+ static let shared = CoreBrightnessDisplayClient()
+
+ private static let builtInDisplayID: UInt64 = 0
+
+ private var clientInstance: NSObject?
+ private let getSelector = NSSelectorFromString("brightnessForDisplay:")
+ private let setSelector = NSSelectorFromString("setBrightness:forDisplay:")
+ private let notificationSelector = NSSelectorFromString("setNotificationBlock:")
+
+ var onBrightnessChange: ((Float) -> Void)?
+ private var available = false
+
+ private init() {
+ var loaded = false
+ let bundlePaths = [
+ "/System/Library/PrivateFrameworks/CoreBrightness.framework",
+ "/System/Library/PrivateFrameworks/CoreBrightness.framework/CoreBrightness"
+ ]
+ for path in bundlePaths where !loaded {
+ if let bundle = Bundle(path: path) {
+ loaded = bundle.load()
+ }
+ }
+ guard loaded, let cls = NSClassFromString("DisplayBrightnessClient") as? NSObject.Type else {
+ NSLog("⚠️ CoreBrightnessDisplayClient: DisplayBrightnessClient class not found")
+ return
+ }
+ clientInstance = cls.init()
+ available = clientInstance != nil
+ }
+
+ var isAvailable: Bool { available }
+
+ func currentBrightness() -> Float? {
+ guard let clientInstance,
+ let getter: BrightnessGetter = methodIMP(on: clientInstance, selector: getSelector, as: BrightnessGetter.self)
+ else { return nil }
+ let value = getter(clientInstance, getSelector, Self.builtInDisplayID)
+ guard value >= 0, value <= 1 else { return nil }
+ return value
+ }
+
+ func setBrightness(_ value: Float) -> Bool {
+ guard let clientInstance,
+ let setter: BrightnessSetter = methodIMP(on: clientInstance, selector: setSelector, as: BrightnessSetter.self)
+ else { return false }
+ return setter(clientInstance, setSelector, value, Self.builtInDisplayID).boolValue
+ }
+
+ private typealias BrightnessGetter = @convention(c) (NSObject, Selector, UInt64) -> Float
+ private typealias BrightnessSetter = @convention(c) (NSObject, Selector, Float, UInt64) -> ObjCBool
+
+ private func methodIMP(on object: NSObject, selector: Selector, as type: T.Type) -> T? {
+ guard let cls = object_getClass(object),
+ let method = class_getInstanceMethod(cls, selector)
+ else { return nil }
+ let imp = method_getImplementation(method)
+ return unsafeBitCast(imp, to: T.self)
+ }
+}
diff --git a/DynamicIsland/managers/SystemDisplayManager.swift b/DynamicIsland/managers/SystemDisplayManager.swift
index 94195f3..93fa377 100644
--- a/DynamicIsland/managers/SystemDisplayManager.swift
+++ b/DynamicIsland/managers/SystemDisplayManager.swift
@@ -46,7 +46,7 @@ class SystemDisplayManager {
private static func getStandardDisplayBrightness() throws -> Float {
var brightness: float_t = 1
- let service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IODisplayConnect"))
+ let service = IOServiceGetMatchingService(kIOMainPortDefault, IOServiceMatching("IODisplayConnect"))
defer {
IOObjectRelease(service)
}
diff --git a/DynamicIsland/managers/SystemMediaControllers.swift b/DynamicIsland/managers/SystemMediaControllers.swift
index d873e04..f61c8d7 100644
--- a/DynamicIsland/managers/SystemMediaControllers.swift
+++ b/DynamicIsland/managers/SystemMediaControllers.swift
@@ -476,6 +476,10 @@ final class SystemBrightnessController {
private let maximumBrightnessAnimationDuration: TimeInterval = 0.3
private let brightnessAnimationDurationScale: TimeInterval = 1.6
private var lastEmittedBrightness: Float = 0.5
+ private let coreBrightnessClient = CoreBrightnessDisplayClient.shared
+ private var pollTimer: Timer?
+ private let pollInterval: TimeInterval = 0.15
+ private let pollChangeThreshold: Float = 0.005
private init() {
registerExternalNotifications()
@@ -484,12 +488,15 @@ final class SystemBrightnessController {
func start() {
notifyCurrentBrightness()
+ startPollingIfNeeded()
}
func stop() {
onBrightnessChange = nil
brightnessAnimationTimer?.invalidate()
brightnessAnimationTimer = nil
+ pollTimer?.invalidate()
+ pollTimer = nil
}
func adjust(by delta: Float) {
@@ -506,6 +513,9 @@ final class SystemBrightnessController {
}
var currentBrightness: Float {
+ if let level = coreBrightnessClient.currentBrightness() {
+ return level
+ }
if let level = getBrightnessViaDisplayServices() {
return level
}
@@ -583,6 +593,9 @@ final class SystemBrightnessController {
private func applyBrightness(_ value: Float) {
let clamped = max(0, min(1, value))
+ if coreBrightnessClient.setBrightness(clamped) {
+ return
+ }
if setBrightnessViaDisplayServices(clamped) {
return
}
@@ -667,7 +680,8 @@ final class SystemBrightnessController {
let names = [
Notification.Name("com.apple.BezelEngine.BrightnessChanged"),
Notification.Name("com.apple.BezelServices.BrightnessChanged"),
- Notification.Name("com.apple.controlcenter.display.brightness")
+ Notification.Name("com.apple.controlcenter.display.brightness"),
+ Notification.Name("com.apple.CoreBrightness.DisplayBrightnessChanged")
]
observers = names.map { name in
DistributedNotificationCenter.default().addObserver(forName: name, object: nil, queue: .main) { [weak self] _ in
@@ -677,8 +691,20 @@ final class SystemBrightnessController {
notificationsInstalled = true
}
+ private func startPollingIfNeeded() {
+ guard pollTimer == nil else { return }
+ pollTimer = Timer.scheduledTimer(withTimeInterval: pollInterval, repeats: true) { [weak self] _ in
+ guard let self else { return }
+ let system = self.currentBrightness
+ if abs(system - self.lastEmittedBrightness) > self.pollChangeThreshold {
+ self.emitBrightnessChange(value: system)
+ }
+ }
+ }
+
deinit {
brightnessAnimationTimer?.invalidate()
+ pollTimer?.invalidate()
observers.forEach { DistributedNotificationCenter.default().removeObserver($0) }
}
}