Live Activities unter der Notch, nicht daneben
Neben ihr wären die Arme zwangsläufig gleich breit — die Silhouette zeichnet den Steg mittig um die Hardware. Ein Symbol links und ein Balken rechts hieße dann 132 Punkte Schwarz für ein Symbol. Darunter hängt die Fläche frei und wird so breit, wie ihr Inhalt es braucht. Lautstärke, Strom, Titelwechsel und Helligkeit. Gemeldet wird nur, was sich **geändert** hat: `PowerWatcher` schweigt beim ersten gelesenen Zustand, sonst begrüßte Onyx jeden Start mit „am Netz". Die Helligkeit kostete einen Spike. Von drei Wegen trägt nur `DisplayServices`, und nur für den eingebauten Bildschirm. `CoreDisplay` — der Weg, den jede Anleitung empfiehlt — gibt für alle Bildschirme 1.0 zurück, auch für den, der auf 62 % stand. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
c05ccb8ae1
commit
9b600de9a9
@@ -0,0 +1,81 @@
|
||||
import AppKit
|
||||
import IOKit
|
||||
|
||||
// Gibt es einen benutzbaren Weg, die Bildschirmhelligkeit zu *lesen* — und
|
||||
// besser noch: auf ihre Änderung zu *hören*?
|
||||
//
|
||||
// Öffentlich gibt es keinen. Geprüft werden deshalb drei private bzw.
|
||||
// halböffentliche Wege, jeder einzeln, damit hinterher klar ist, welcher trägt
|
||||
// und welcher nur auf manchen Geräten funktioniert.
|
||||
|
||||
let displays: [CGDirectDisplayID] = NSScreen.screens.compactMap {
|
||||
$0.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? CGDirectDisplayID
|
||||
}
|
||||
print("Bildschirme: \(displays)\n")
|
||||
|
||||
// MARK: - Weg 1: DisplayServices
|
||||
|
||||
typealias GetBrightness = @convention(c) (CGDirectDisplayID, UnsafeMutablePointer<Float>) -> Int32
|
||||
typealias RegisterNotify = @convention(c) (CGDirectDisplayID, UnsafeRawPointer?, UnsafeRawPointer?) -> Int32
|
||||
|
||||
let dsPath = "/System/Library/PrivateFrameworks/DisplayServices.framework/DisplayServices"
|
||||
if let handle = dlopen(dsPath, RTLD_LAZY) {
|
||||
print("DisplayServices: geladen")
|
||||
if let sym = dlsym(handle, "DisplayServicesGetBrightness") {
|
||||
let fn = unsafeBitCast(sym, to: GetBrightness.self)
|
||||
for id in displays {
|
||||
var value: Float = -1
|
||||
let status = fn(id, &value)
|
||||
print(" GetBrightness(\(id)) → status \(status), Wert \(value)")
|
||||
}
|
||||
} else {
|
||||
print(" DisplayServicesGetBrightness: nicht vorhanden")
|
||||
}
|
||||
print(" RegisterForBrightnessChangeNotifications: " +
|
||||
(dlsym(handle, "DisplayServicesRegisterForBrightnessChangeNotifications") != nil
|
||||
? "vorhanden" : "FEHLT"))
|
||||
} else {
|
||||
print("DisplayServices: nicht ladbar — \(String(cString: dlerror()))")
|
||||
}
|
||||
|
||||
// MARK: - Weg 2: CoreDisplay
|
||||
|
||||
typealias UserBrightness = @convention(c) (CGDirectDisplayID) -> Double
|
||||
|
||||
let cdPath = "/System/Library/Frameworks/CoreDisplay.framework/CoreDisplay"
|
||||
if let handle = dlopen(cdPath, RTLD_LAZY) {
|
||||
print("\nCoreDisplay: geladen")
|
||||
if let sym = dlsym(handle, "CoreDisplay_Display_GetUserBrightness") {
|
||||
let fn = unsafeBitCast(sym, to: UserBrightness.self)
|
||||
for id in displays {
|
||||
print(" GetUserBrightness(\(id)) → \(fn(id))")
|
||||
}
|
||||
} else {
|
||||
print(" CoreDisplay_Display_GetUserBrightness: nicht vorhanden")
|
||||
}
|
||||
} else {
|
||||
print("\nCoreDisplay: nicht ladbar")
|
||||
}
|
||||
|
||||
// MARK: - Weg 3: IOKit
|
||||
|
||||
print("\nIOKit IODisplayGetFloatParameter:")
|
||||
var iterator = io_iterator_t()
|
||||
let matching = IOServiceMatching("IODisplayConnect")
|
||||
if IOServiceGetMatchingServices(kIOMainPortDefault, matching, &iterator) == KERN_SUCCESS {
|
||||
var found = false
|
||||
var service = IOIteratorNext(iterator)
|
||||
while service != 0 {
|
||||
found = true
|
||||
var brightness: Float = -1
|
||||
let status = IODisplayGetFloatParameter(service, 0, kIODisplayBrightnessKey as CFString,
|
||||
&brightness)
|
||||
print(" Dienst \(service) → status \(status), Wert \(brightness)")
|
||||
IOObjectRelease(service)
|
||||
service = IOIteratorNext(iterator)
|
||||
}
|
||||
if !found { print(" kein IODisplayConnect gefunden (auf Apple Silicon üblich)") }
|
||||
IOObjectRelease(iterator)
|
||||
} else {
|
||||
print(" IOServiceGetMatchingServices fehlgeschlagen")
|
||||
}
|
||||
Reference in New Issue
Block a user