From 2dd284370b11c5570de17467df898eee04c68be4 Mon Sep 17 00:00:00 2001 From: waydabber <37590873+waydabber@users.noreply.github.com> Date: Fri, 13 Aug 2021 20:44:29 +0200 Subject: [PATCH] Improved software dimming --- MonitorControl/AppDelegate.swift | 5 ++- MonitorControl/Info.plist | 2 +- MonitorControl/Model/Display.swift | 40 +++++++++++++++++--- MonitorControl/Model/ExternalDisplay.swift | 4 +- MonitorControl/UI/Base.lproj/Main.storyboard | 6 +-- MonitorControlHelper/Info.plist | 2 +- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/MonitorControl/AppDelegate.swift b/MonitorControl/AppDelegate.swift index c2e3fca..96548e9 100644 --- a/MonitorControl/AppDelegate.swift +++ b/MonitorControl/AppDelegate.swift @@ -19,6 +19,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { var accessibilityObserver: NSObjectProtocol! var reconfigureID: Int = 0 // dispatched reconfigure command ID var sleepID: Int = 0 // Don't reconfigure display as the system or display is sleeping or wake just recently. + let debugSw: Bool = false lazy var preferencesWindowController: PreferencesWindowController = { let storyboard = NSStoryboard(name: "Main", bundle: Bundle.main) let mainPrefsVc = storyboard.instantiateController(withIdentifier: "MainPrefsVC") as? MainPrefsViewController @@ -114,7 +115,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { // externalDisplay.arm64ddc = true // } if !serviceMatch.isDiscouraged { - externalDisplay.arm64ddc = true // MARK: (point of interest when testing) + externalDisplay.arm64ddc = !debugSw ? true : false // MARK: (point of interest when testing) } } } @@ -182,7 +183,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { } } } - if CGDisplayIsBuiltin(onlineDisplayID) != 0 { // MARK: (point of interest for testing) + if !debugSw, CGDisplayIsBuiltin(onlineDisplayID) != 0 { // MARK: (point of interest for testing) display = InternalDisplay(id, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, isVirtual: isVirtual) } else { display = ExternalDisplay(id, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, isVirtual: isVirtual) diff --git a/MonitorControl/Info.plist b/MonitorControl/Info.plist index b38a2d7..d159dbb 100644 --- a/MonitorControl/Info.plist +++ b/MonitorControl/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion - 2077 + 2156 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/MonitorControl/Model/Display.swift b/MonitorControl/Model/Display.swift index 705bacb..fbcc836 100644 --- a/MonitorControl/Model/Display.swift +++ b/MonitorControl/Model/Display.swift @@ -23,7 +23,7 @@ class Display { internal var modelNumber: UInt32? internal var isEnabled: Bool { get { - return self.prefs.object(forKey: "\(self.identifier)-state") as? Bool ?? true + self.prefs.object(forKey: "\(self.identifier)-state") as? Bool ?? true } set { self.prefs.set(newValue, forKey: "\(self.identifier)-state") @@ -69,11 +69,40 @@ class Display { return self.identifier } - func setSwBrightness(value: UInt8) -> Bool { + func swBrightnessTransform(value: Float, reverse: Bool = false) -> Float { + let lowTreshold: Float = 0.05 // We don't allow decrease lower than 5% for safety reasons and because some displays blank off after a while on full screen black + if !reverse { + return value * (1 - lowTreshold) + lowTreshold + } else { + return (value - lowTreshold) / (1 - lowTreshold) + } + } + + func setSwBrightness(value: UInt8, fast: Bool = false) -> Bool { + var redMin: CGGammaValue = 0 + var redMax: CGGammaValue = 0 + var redGamma: CGGammaValue = 0 + var greenMin: CGGammaValue = 0 + var greenMax: CGGammaValue = 0 + var greenGamma: CGGammaValue = 0 + var blueMin: CGGammaValue = 0 + var blueMax: CGGammaValue = 0 + var blueGamma: CGGammaValue = 0 let brightnessValue: UInt8 = min(getSwMaxBrightness(), value) var floatValue = Float(Float(brightnessValue) / Float(self.getSwMaxBrightness())) - floatValue = floatValue * 0.95 + 0.05 // We don't allow decrease lower than 5% for safety reasons and because some displays blank off after a while on full screen black - if CGSetDisplayTransferByFormula(self.identifier, 0, floatValue, 1, 0, floatValue, 1, 0, floatValue, 1) == CGError.success { + floatValue = self.swBrightnessTransform(value: floatValue) + os_log("setting software brightness to: %{public}@", type: .debug, String(floatValue)) + if CGGetDisplayTransferByFormula(self.identifier, &redMin, &redMax, &redGamma, &greenMin, &greenMax, &greenGamma, &blueMin, &blueMax, &blueGamma) == CGError.success { + if !fast { + DispatchQueue.global(qos: .userInitiated).async { + for value in stride(from: redMax, to: floatValue, by: 0.0025 * (redMax > floatValue ? -1 : 1)) { + CGSetDisplayTransferByFormula(self.identifier, 0, value, redGamma, 0, value, greenGamma, 0, value, blueGamma) + Thread.sleep(forTimeInterval: 0.001) + } + } + } else { + CGSetDisplayTransferByFormula(self.identifier, 0, floatValue, redGamma, 0, floatValue, greenGamma, 0, floatValue, blueGamma) + } self.saveSwBirghtnessPrefValue(Int(brightnessValue)) return true } @@ -91,7 +120,8 @@ class Display { var blueMax: CGGammaValue = 0 var blueGamma: CGGammaValue = 0 if CGGetDisplayTransferByFormula(self.identifier, &redMin, &redMax, &redGamma, &greenMin, &greenMax, &greenGamma, &blueMin, &blueMax, &blueGamma) == CGError.success { - let brightnessValue = UInt8(min(max(redMax, greenMax, blueMax), 1) * Float(self.getSwMaxBrightness())) + let brightnessValue = UInt8(round(swBrightnessTransform(value: max(redMax, greenMax, blueMax), reverse: true) * Float(self.getSwMaxBrightness()))) + os_log("Current read software brightness is: %{public}@", type: .debug, String(brightnessValue)) return brightnessValue } return self.getSwMaxBrightness() diff --git a/MonitorControl/Model/ExternalDisplay.swift b/MonitorControl/Model/ExternalDisplay.swift index 15d167a..6e78dc9 100644 --- a/MonitorControl/Model/ExternalDisplay.swift +++ b/MonitorControl/Model/ExternalDisplay.swift @@ -186,13 +186,13 @@ class ExternalDisplay: Display { } if swAfterBirghtnessMode { - let currentSwBrightness: UInt8 = self.getSwBrightness() + let currentSwBrightness = UInt8(self.getSwBrightnessPrefValue()) var swBirghtnessValue = self.calcNewValue(currentValue: Int(currentSwBrightness), maxValue: Int(getSwMaxBrightness()), isUp: isUp, isSmallIncrement: isSmallIncrement) if swBirghtnessValue >= Int(getSwMaxBrightness()) { swBirghtnessValue = Int(getSwMaxBrightness()) swAfterBirghtnessMode = false } - if self.setSwBrightness(value: UInt8(swBirghtnessValue)) { + if self.setSwBrightness(value: UInt8(swBirghtnessValue), fast: true) { self.showOsd(command: .brightness, value: self.getValue(for: .brightness), roundChiclet: !isSmallIncrement) } } diff --git a/MonitorControl/UI/Base.lproj/Main.storyboard b/MonitorControl/UI/Base.lproj/Main.storyboard index d868055..54db928 100644 --- a/MonitorControl/UI/Base.lproj/Main.storyboard +++ b/MonitorControl/UI/Base.lproj/Main.storyboard @@ -308,8 +308,8 @@ - - + + @@ -589,7 +589,7 @@ - + diff --git a/MonitorControlHelper/Info.plist b/MonitorControlHelper/Info.plist index 0dd79fa..85c8627 100644 --- a/MonitorControlHelper/Info.plist +++ b/MonitorControlHelper/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion - 2077 + 2156 LSApplicationCategoryType public.app-category.utilities LSBackgroundOnly