import SwiftUI import AppKit import OnyxDesign import OnyxHelperProtocol /// Wer das Ladelimit **lesen** kann. /// /// Nur lesen, und das ist eine gemessene Grenze, keine Bequemlichkeit: der /// SMC lehnt Schreibzugriffe auf `CHLT` ab. Der Helfer hat es versucht und /// `false` gemeldet, der Wert blieb unverändert. macOS setzt das Limit /// offenbar auf einem anderen Weg als über den SMC-Userclient. /// /// Ein Regler, der sich ziehen lässt und dann zurückspringt, ist schlimmer als /// gar keiner — er behauptet eine Fähigkeit, die nicht existiert. @MainActor public protocol ChargeLimitReading: AnyObject { /// Das eingestellte Limit in Prozent, `nil` wenn keines gilt. var chargeLimit: Int? { get } /// Ob der Wert überhaupt gelesen werden kann — ohne Helfer nicht. var canReadCharge: Bool { get } func refreshChargeLimit() } /// Zeigt das Ladelimit und führt dorthin, wo man es ändern kann. public struct ChargeLimitControl: View { private let control: any ChargeLimitReading /// Im Popover ist Platz für den Hinweis, in der Kachel nicht. private let roomy: Bool public init(control: any ChargeLimitReading, roomy: Bool) { self.control = control self.roomy = roomy } public var body: some View { HStack(spacing: 6) { Text("charge.limit", bundle: .module) .font(Onyx.Font.caption) .foregroundStyle(Onyx.Color.textSecondary) Spacer(minLength: 4) if let limit = control.chargeLimit, limit < ChargeSafety.noLimit { Text(verbatim: "\(limit) %") .font(Onyx.Font.metricSmall).monospacedDigit() .foregroundStyle(Onyx.Color.accent) } else if control.canReadCharge { Text("charge.limit.off", bundle: .module) .font(Onyx.Font.metricSmall) .foregroundStyle(Onyx.Color.textTertiary) } else { Text(verbatim: "–") .font(Onyx.Font.metricSmall) .foregroundStyle(Onyx.Color.textTertiary) } if roomy { // Kein Regler, sondern der Weg dorthin, wo es wirklich geht. Button { NSWorkspace.shared.open( URL(string: "x-apple.systempreferences:com.apple.Battery-Settings.extension")!) } label: { Image(systemName: "arrow.up.forward.app") .font(.system(size: 10)) .foregroundStyle(Onyx.Color.textTertiary) } .buttonStyle(.plain) .help(Text("charge.limit.inSystemSettings", bundle: .module)) } } .onAppear { control.refreshChargeLimit() } } }