Skip to content

Commit d34cf38

Browse files
authored
Multiple attempts to write last DDC settings after wake when 'Apply last saved settings' is enabled (MonitorControl#734)
1 parent 5567ae4 commit d34cf38

File tree

6 files changed

+72
-46
lines changed

6 files changed

+72
-46
lines changed

MonitorControl/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<key>CFBundleShortVersionString</key>
2020
<string>$(MARKETING_VERSION)</string>
2121
<key>CFBundleVersion</key>
22-
<string>6767</string>
22+
<string>6795</string>
2323
<key>LSApplicationCategoryType</key>
2424
<string>public.app-category.utilities</string>
2525
<key>LSMinimumSystemVersion</key>

MonitorControl/Model/OtherDisplay.swift

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,10 @@ import IOKit
55
import os.log
66

77
class OtherDisplay: Display {
8-
var volumeSliderHandler: SliderHandler?
9-
var contrastSliderHandler: SliderHandler?
108
var ddc: IntelDDC?
119
var arm64ddc: Bool = false
1210
var arm64avService: IOAVService?
1311
var isDiscouraged: Bool = false
14-
let DDC_MAX_DETECT_LIMIT: Int = 100
1512
var pollingCount: Int {
1613
get {
1714
switch self.readPrefAsInt(key: .pollingMode) {
@@ -33,8 +30,8 @@ class OtherDisplay: Display {
3330
}
3431
}
3532

36-
func processCurrentDDCValue(read: Bool, command: Command, firstrun: Bool, currentDDCValue: UInt16) {
37-
if read {
33+
func processCurrentDDCValue(isReadFromDisplay: Bool, command: Command, firstrun: Bool, currentDDCValue: UInt16) {
34+
if isReadFromDisplay {
3835
var currentValue = self.convDDCToValue(for: command, from: currentDDCValue)
3936
if !prefs.bool(forKey: PrefKey.disableCombinedBrightness.rawValue), command == .brightness {
4037
os_log("- Combined brightness mapping on DDC data.", type: .info)
@@ -71,17 +68,34 @@ class OtherDisplay: Display {
7168
}
7269
}
7370

71+
func getDDCValueFromPrefs(_ command: Command) -> UInt16 {
72+
return self.convValueToDDC(for: command, from: (!prefs.bool(forKey: PrefKey.disableCombinedBrightness.rawValue) && command == .brightness) ? max(0, self.readPrefAsFloat(for: command) - self.combinedBrightnessSwitchingValue()) * (1 / (1 - self.combinedBrightnessSwitchingValue())) : self.readPrefAsFloat(for: command))
73+
}
74+
75+
func restoreDDCSettingsToDisplay(command: Command) {
76+
if !self.smoothBrightnessRunning, !self.isSw(), !self.readPrefAsBool(key: .unavailableDDC, for: command), self.readPrefAsBool(key: .isTouched, for: command), prefs.integer(forKey: PrefKey.startupAction.rawValue) == StartupAction.write.rawValue, !app.safeMode {
77+
let restoreValue = self.getDDCValueFromPrefs(command)
78+
os_log("Restoring %{public}@ DDC value %{public}@ for %{public}@", type: .info, String(reflecting: command), String(restoreValue), self.name)
79+
_ = self.writeDDCValues(command: command, value: restoreValue)
80+
if command == .audioSpeakerVolume, self.readPrefAsBool(key: .enableMuteUnmute) {
81+
let currentMuteValue = self.readPrefAsInt(for: .audioMuteScreenBlank) == 0 ? 2 : self.readPrefAsInt(for: .audioMuteScreenBlank)
82+
os_log("- Writing last saved DDC value for Mute: %{public}@", type: .info, String(currentMuteValue))
83+
_ = self.writeDDCValues(command: .audioMuteScreenBlank, value: UInt16(currentMuteValue))
84+
}
85+
}
86+
}
87+
7488
func setupCurrentAndMaxValues(command: Command, firstrun: Bool = false) {
7589
var ddcValues: (UInt16, UInt16)?
7690
var maxDDCValue = UInt16(DDC_MAX_DETECT_LIMIT)
7791
var currentDDCValue: UInt16
7892
switch command {
79-
case .audioSpeakerVolume: currentDDCValue = UInt16(Float(self.DDC_MAX_DETECT_LIMIT) * 0.125)
80-
case .contrast: currentDDCValue = UInt16(Float(self.DDC_MAX_DETECT_LIMIT) * 0.750)
81-
default: currentDDCValue = UInt16(Float(self.DDC_MAX_DETECT_LIMIT) * 1.000)
93+
case .audioSpeakerVolume: currentDDCValue = UInt16(Float(DDC_MAX_DETECT_LIMIT) * 0.125)
94+
case .contrast: currentDDCValue = UInt16(Float(DDC_MAX_DETECT_LIMIT) * 0.750)
95+
default: currentDDCValue = UInt16(Float(DDC_MAX_DETECT_LIMIT) * 1.000)
8296
}
8397
if command == .audioSpeakerVolume {
84-
currentDDCValue = UInt16(Float(self.DDC_MAX_DETECT_LIMIT) * 0.125) // lower default audio value as high volume might rattle the user.
98+
currentDDCValue = UInt16(Float(DDC_MAX_DETECT_LIMIT) * 0.125) // lower default audio value as high volume might rattle the user.
8599
}
86100
os_log("Setting up display %{public}@ for %{public}@", type: .info, String(self.identifier), String(reflecting: command))
87101
if !self.isSw() {
@@ -91,7 +105,7 @@ class OtherDisplay: Display {
91105
ddcValues = self.readDDCValues(for: command, tries: UInt(self.pollingCount), minReplyDelay: delay)
92106
if ddcValues != nil {
93107
(currentDDCValue, maxDDCValue) = ddcValues ?? (currentDDCValue, maxDDCValue)
94-
self.processCurrentDDCValue(read: true, command: command, firstrun: firstrun, currentDDCValue: currentDDCValue)
108+
self.processCurrentDDCValue(isReadFromDisplay: true, command: command, firstrun: firstrun, currentDDCValue: currentDDCValue)
95109
os_log("- DDC read successful.", type: .info)
96110
} else {
97111
os_log("- DDC read failed.", type: .info)
@@ -102,58 +116,46 @@ class OtherDisplay: Display {
102116
if self.readPrefAsInt(key: .maxDDCOverride, for: command) > self.readPrefAsInt(key: .minDDCOverride, for: command) {
103117
self.savePref(self.readPrefAsInt(key: .maxDDCOverride, for: command), key: .maxDDC, for: command)
104118
} else {
105-
self.savePref(min(Int(maxDDCValue), self.DDC_MAX_DETECT_LIMIT), key: .maxDDC, for: command)
119+
self.savePref(min(Int(maxDDCValue), DDC_MAX_DETECT_LIMIT), key: .maxDDC, for: command)
106120
}
107121
if ddcValues == nil {
108-
self.processCurrentDDCValue(read: false, command: command, firstrun: firstrun, currentDDCValue: currentDDCValue)
109-
currentDDCValue = self.convValueToDDC(for: command, from: (!prefs.bool(forKey: PrefKey.disableCombinedBrightness.rawValue) && command == .brightness) ? max(0, self.readPrefAsFloat(for: command) - self.combinedBrightnessSwitchingValue()) * (1 / (1 - self.combinedBrightnessSwitchingValue())) : self.readPrefAsFloat(for: command))
122+
self.processCurrentDDCValue(isReadFromDisplay: false, command: command, firstrun: firstrun, currentDDCValue: currentDDCValue)
123+
currentDDCValue = self.getDDCValueFromPrefs(command)
110124
}
111125
os_log("- Current DDC value: %{public}@", type: .info, String(currentDDCValue))
112126
os_log("- Minimum DDC value: %{public}@ (overrides 0)", type: .info, String(self.readPrefAsInt(key: .minDDCOverride, for: command)))
113127
os_log("- Maximum DDC value: %{public}@ (overrides %{public}@)", type: .info, String(self.readPrefAsInt(key: .maxDDC, for: command)), String(maxDDCValue))
114128
os_log("- Current internal value: %{public}@", type: .info, String(self.readPrefAsFloat(for: command)))
115129
os_log("- Command status: %{public}@", type: .info, self.readPrefAsBool(key: .isTouched, for: command) ? "Touched" : "Untouched")
116-
if self.readPrefAsBool(key: .isTouched, for: command), prefs.integer(forKey: PrefKey.startupAction.rawValue) == StartupAction.write.rawValue, !app.safeMode {
117-
os_log("- Writing last saved DDC values.", type: .info, self.name, String(reflecting: command))
118-
_ = self.writeDDCValues(command: command, value: currentDDCValue)
130+
if command == .audioSpeakerVolume {
131+
self.setupMuteUnMute()
119132
}
133+
self.restoreDDCSettingsToDisplay(command: command)
120134
} else {
121135
self.savePref(self.prefExists(for: command) ? self.readPrefAsFloat(for: command) : Float(1), for: command)
122136
self.savePref(self.readPrefAsFloat(for: command), key: .SwBrightness)
123137
self.brightnessSyncSourceValue = self.readPrefAsFloat(for: command)
124138
self.smoothBrightnessTransient = self.readPrefAsFloat(for: command)
125139
os_log("- Software controlled display current internal value: %{public}@", type: .info, String(self.readPrefAsFloat(for: command)))
126140
}
127-
if command == .audioSpeakerVolume {
128-
self.setupMuteUnMute()
129-
}
130141
}
131142

132143
func setupMuteUnMute() {
133-
guard !self.readPrefAsBool(key: .unavailableDDC, for: .audioSpeakerVolume) else {
144+
guard !self.isSw(), !self.readPrefAsBool(key: .unavailableDDC, for: .audioSpeakerVolume), self.readPrefAsBool(key: .enableMuteUnmute) else {
134145
return
135146
}
136-
var currentMuteValue = self.readPrefAsInt(for: .audioMuteScreenBlank)
137-
currentMuteValue = currentMuteValue == 0 ? 2 : currentMuteValue
138-
var muteValues: (current: UInt16, max: UInt16)?
139-
if self.readPrefAsBool(key: .enableMuteUnmute) {
140-
if self.pollingCount != 0, !app.safeMode, prefs.integer(forKey: PrefKey.startupAction.rawValue) == StartupAction.read.rawValue {
141-
os_log("Reading DDC from display %{public}@ times for Mute", type: .info, String(self.pollingCount))
142-
let delay = self.readPrefAsBool(key: .longerDelay) ? UInt64(40 * kMillisecondScale) : nil
143-
muteValues = self.readDDCValues(for: .audioMuteScreenBlank, tries: UInt(self.pollingCount), minReplyDelay: delay)
144-
if let muteValues = muteValues {
145-
os_log("Success, current Mute setting: %{public}@", type: .info, String(muteValues.current))
146-
currentMuteValue = Int(muteValues.current)
147-
} else {
148-
os_log("Mute read failed", type: .info)
149-
}
150-
}
151-
if self.readPrefAsBool(key: .isTouched, for: .audioSpeakerVolume), prefs.integer(forKey: PrefKey.startupAction.rawValue) == StartupAction.write.rawValue, !app.safeMode {
152-
os_log("Writing last saved DDC value for Mute: %{public}@", type: .info, String(currentMuteValue))
153-
_ = self.writeDDCValues(command: .audioMuteScreenBlank, value: UInt16(currentMuteValue))
147+
var currentMuteValue = self.readPrefAsInt(for: .audioMuteScreenBlank) == 0 ? 2 : self.readPrefAsInt(for: .audioMuteScreenBlank)
148+
if self.pollingCount != 0, !app.safeMode, prefs.integer(forKey: PrefKey.startupAction.rawValue) == StartupAction.read.rawValue {
149+
os_log("- Reading DDC from display %{public}@ times for Mute", type: .info, String(self.pollingCount))
150+
let delay = self.readPrefAsBool(key: .longerDelay) ? UInt64(40 * kMillisecondScale) : nil
151+
if let muteValues: (current: UInt16, max: UInt16) = self.readDDCValues(for: .audioMuteScreenBlank, tries: UInt(self.pollingCount), minReplyDelay: delay) {
152+
os_log("- Success, current Mute setting: %{public}@", type: .info, String(muteValues.current))
153+
currentMuteValue = Int(muteValues.current)
154+
} else {
155+
os_log("- Mute read failed", type: .info)
154156
}
155-
self.savePref(Int(currentMuteValue), for: .audioMuteScreenBlank)
156157
}
158+
self.savePref(Int(currentMuteValue), for: .audioMuteScreenBlank)
157159
}
158160

159161
func setupSliderCurrentValue(command: Command) -> Float {

MonitorControl/Support/AppDelegate.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
2020
var sleepID: Int = 0 // sleep event ID
2121
var safeMode = false
2222
var jobRunning = false
23+
var startupActionWriteCounter: Int = 0
2324
var audioPlayer: AVAudioPlayer?
2425
let updaterController = SPUStandardUpdaterController(startingUpdater: false, updaterDelegate: UpdaterDelegate(), userDriverDelegate: nil)
2526

@@ -201,6 +202,23 @@ class AppDelegate: NSObject, NSApplicationDelegate {
201202
DisplayManager.shared.updateArm64AVServices()
202203
self.job(start: true)
203204
}
205+
self.startupActionWriteRepeatAfterSober()
206+
}
207+
}
208+
209+
private func startupActionWriteRepeatAfterSober(dispatchedCounter: Int = 0) {
210+
let counter = dispatchedCounter == 0 ? 10 : dispatchedCounter
211+
self.startupActionWriteCounter = dispatchedCounter == 0 ? counter : self.startupActionWriteCounter
212+
guard prefs.integer(forKey: PrefKey.startupAction.rawValue) == StartupAction.write.rawValue, self.startupActionWriteCounter == counter else {
213+
return
214+
}
215+
os_log("Sober write action repeat for DDC - %{public}@", type: .info, String(counter))
216+
DisplayManager.shared.restoreOtherDisplays()
217+
self.startupActionWriteCounter = counter - 1
218+
if counter > 1 {
219+
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
220+
self.startupActionWriteRepeatAfterSober(dispatchedCounter: counter - 1)
221+
}
204222
}
205223
}
206224

MonitorControl/Support/DisplayManager.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,8 @@ class DisplayManager {
179179

180180
func setupOtherDisplays(firstrun: Bool = false) {
181181
for otherDisplay in self.getOtherDisplays() {
182-
if !otherDisplay.isSw(), !otherDisplay.readPrefAsBool(key: .unavailableDDC, for: .audioSpeakerVolume) {
183-
otherDisplay.setupCurrentAndMaxValues(command: .audioSpeakerVolume, firstrun: firstrun)
184-
}
185-
if !otherDisplay.isSw(), !otherDisplay.readPrefAsBool(key: .unavailableDDC, for: .contrast) {
186-
otherDisplay.setupCurrentAndMaxValues(command: .contrast, firstrun: firstrun)
182+
for command in [Command.audioSpeakerVolume, Command.contrast] where !otherDisplay.readPrefAsBool(key: .unavailableDDC, for: command) && !otherDisplay.isSw() {
183+
otherDisplay.setupCurrentAndMaxValues(command: command, firstrun: firstrun)
187184
}
188185
if (!otherDisplay.isSw() && !otherDisplay.readPrefAsBool(key: .unavailableDDC, for: .brightness)) || otherDisplay.isSw() {
189186
otherDisplay.setupCurrentAndMaxValues(command: .brightness, firstrun: firstrun)
@@ -192,6 +189,14 @@ class DisplayManager {
192189
}
193190
}
194191

192+
func restoreOtherDisplays() {
193+
for otherDisplay in self.getDdcCapableDisplays() {
194+
for command in [Command.contrast, Command.brightness] where !otherDisplay.readPrefAsBool(key: .unavailableDDC, for: command) {
195+
otherDisplay.restoreDDCSettingsToDisplay(command: command)
196+
}
197+
}
198+
}
199+
195200
func normalizedName(_ name: String) -> String {
196201
var normalizedName = name.replacingOccurrences(of: "(", with: "")
197202
normalizedName = normalizedName.replacingOccurrences(of: ")", with: "")

MonitorControl/main.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ let DEBUG_SW = false
77
let DEBUG_VIRTUAL = false
88
let DEBUG_MACOS10 = false
99
let DEBUG_GAMMA_ENFORCER = false
10+
let DDC_MAX_DETECT_LIMIT: Int = 100
1011

1112
let MIN_PREVIOUS_BUILD_NUMBER = 6262
1213

MonitorControlHelper/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<key>CFBundleShortVersionString</key>
2020
<string>$(MARKETING_VERSION)</string>
2121
<key>CFBundleVersion</key>
22-
<string>6767</string>
22+
<string>6795</string>
2323
<key>LSApplicationCategoryType</key>
2424
<string>public.app-category.utilities</string>
2525
<key>LSBackgroundOnly</key>

0 commit comments

Comments
 (0)