Skip to content

Commit 8309d1d

Browse files
authored
Restore software brightness upon startup + some other tweaks. (MonitorControl#719)
- Software brightness changes are reapplied upon startup when 'Apply last saved values to the display' is selected under 'Upon startup or wake'. - On some rare occasions, macOS does not reset gamma tables upon display reconfiguration which caused an erroneus baseline and double dimming in software and combined mode. Now there is a manual reset upon receiving a reconfiguration request as a safety measure to avoid this. - Some minor tweaks regarding how software dimming and gamma table manipulation behaves. - (also I fixed my name in About.)
1 parent e7f8f04 commit 8309d1d

File tree

20 files changed

+48
-85
lines changed

20 files changed

+48
-85
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>6695</string>
22+
<string>6767</string>
2323
<key>LSApplicationCategoryType</key>
2424
<string>public.app-category.utilities</string>
2525
<key>LSMinimumSystemVersion</key>

MonitorControl/Model/Display.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,13 @@ class Display: Equatable {
200200
}
201201
}
202202

203-
func setSwBrightness(_ value: Float, smooth: Bool = false) -> Bool {
203+
func setSwBrightness(_ value: Float, smooth: Bool = false, noPrefSave: Bool = false) -> Bool {
204204
self.swBrightnessSemaphore.wait()
205205
let brightnessValue = min(1, value)
206206
var currentValue = self.readPrefAsFloat(key: .SwBrightness)
207-
self.savePref(brightnessValue, key: .SwBrightness)
207+
if !noPrefSave {
208+
self.savePref(brightnessValue, key: .SwBrightness)
209+
}
208210
var newValue = brightnessValue
209211
currentValue = self.swBrightnessTransform(value: currentValue)
210212
newValue = self.swBrightnessTransform(value: newValue)

MonitorControl/Model/OtherDisplay.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class OtherDisplay: Display {
4040
os_log("- Combined brightness mapping on DDC data.", type: .info)
4141
if currentValue > 0 {
4242
currentValue = self.combinedBrightnessSwitchingValue() + currentValue * (1 - self.combinedBrightnessSwitchingValue())
43-
} else if currentValue == 0, firstrun {
43+
} else if currentValue == 0, firstrun, prefs.integer(forKey: PrefKey.startupAction.rawValue) != StartupAction.write.rawValue {
4444
currentValue = self.combinedBrightnessSwitchingValue()
4545
} else if self.prefExists(for: command), self.readPrefAsFloat(for: command) <= self.combinedBrightnessSwitchingValue() {
4646
currentValue = self.readPrefAsFloat(for: command)
@@ -58,7 +58,7 @@ class OtherDisplay: Display {
5858
os_log("- Combined brightness mapping on saved data.", type: .info)
5959
if !self.prefExists(for: command) {
6060
currentValue = self.combinedBrightnessSwitchingValue() + self.convDDCToValue(for: command, from: currentDDCValue) * (1 - self.combinedBrightnessSwitchingValue())
61-
} else if firstrun, currentValue < self.combinedBrightnessSwitchingValue() {
61+
} else if firstrun, currentValue < self.combinedBrightnessSwitchingValue(), prefs.integer(forKey: PrefKey.startupAction.rawValue) != StartupAction.write.rawValue {
6262
currentValue = self.combinedBrightnessSwitchingValue()
6363
}
6464
} else {

MonitorControl/Support/AppDelegate.swift

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
100100

101101
func applicationWillTerminate(_: Notification) {
102102
os_log("Goodbye!", type: .info)
103-
DisplayManager.shared.resetSwBrightnessForAllDisplays()
103+
DisplayManager.shared.resetSwBrightnessForAllDisplays(noPrefSave: true)
104104
self.statusItem.isVisible = true
105105
}
106106

@@ -112,7 +112,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
112112
}
113113
}
114114

115-
func displayReconfigured() {
115+
@objc func displayReconfigured() {
116+
DisplayManager.shared.resetSwBrightnessForAllDisplays(noPrefSave: true)
117+
CGDisplayRestoreColorSyncSettings()
116118
self.reconfigureID += 1
117119
os_log("Bumping reconfigureID to %{public}@", type: .info, String(self.reconfigureID))
118120
_ = DisplayManager.shared.destroyAllShades()
@@ -135,12 +137,12 @@ class AppDelegate: NSObject, NSApplicationDelegate {
135137
DisplayManager.shared.configureDisplays()
136138
DisplayManager.shared.addDisplayCounterSuffixes()
137139
DisplayManager.shared.updateArm64AVServices()
138-
if firstrun {
139-
DisplayManager.shared.resetSwBrightnessForAllDisplays(settingsOnly: true)
140+
if firstrun && prefs.integer(forKey: PrefKey.startupAction.rawValue) != StartupAction.write.rawValue {
141+
DisplayManager.shared.resetSwBrightnessForAllDisplays(prefsOnly: true)
140142
}
141143
DisplayManager.shared.setupOtherDisplays(firstrun: firstrun)
142144
self.updateMenusAndKeys()
143-
if !firstrun {
145+
if !firstrun || prefs.integer(forKey: PrefKey.startupAction.rawValue) == StartupAction.write.rawValue {
144146
if !prefs.bool(forKey: PrefKey.disableCombinedBrightness.rawValue) {
145147
DisplayManager.shared.restoreSwBrightnessForAllDisplays(async: !prefs.bool(forKey: PrefKey.disableSmoothBrightness.rawValue))
146148
}
@@ -163,7 +165,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
163165

164166
private func subscribeEventListeners() {
165167
NotificationCenter.default.addObserver(self, selector: #selector(self.audioDeviceChanged), name: Notification.Name.defaultOutputDeviceChanged, object: nil) // subscribe Audio output detector (SimplyCoreAudio)
166-
DistributedNotificationCenter.default.addObserver(self, selector: #selector(self.colorSyncSettingsChanged), name: NSNotification.Name(rawValue: kColorSyncDisplayDeviceProfilesNotification.takeRetainedValue() as String), object: nil) // ColorSync change
168+
DistributedNotificationCenter.default.addObserver(self, selector: #selector(self.displayReconfigured), name: NSNotification.Name(rawValue: kColorSyncDisplayDeviceProfilesNotification.takeRetainedValue() as String), object: nil) // ColorSync change
167169
NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.sleepNotification), name: NSWorkspace.screensDidSleepNotification, object: nil) // sleep and wake listeners
168170
NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.wakeNotofication), name: NSWorkspace.screensDidWakeNotification, object: nil)
169171
NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.sleepNotification), name: NSWorkspace.willSleepNotification, object: nil)
@@ -192,7 +194,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
192194
self.sleepID = 0
193195
if self.reconfigureID != 0 {
194196
let dispatchedReconfigureID = self.reconfigureID
195-
os_log("Display needs reconfig after sober with reconfigureID %{public}@", type: .info, String(dispatchedReconfigureID))
197+
os_log("Displays need reconfig after sober with reconfigureID %{public}@", type: .info, String(dispatchedReconfigureID))
196198
self.configure(dispatchedReconfigureID: dispatchedReconfigureID)
197199
} else if Arm64DDC.isArm64 {
198200
os_log("Displays don't need reconfig after sober but might need AVServices update", type: .info)
@@ -238,11 +240,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
238240
}
239241
}
240242

241-
@objc private func colorSyncSettingsChanged() {
242-
CGDisplayRestoreColorSyncSettings()
243-
self.displayReconfigured()
244-
}
245-
246243
func handleListenForChanged() {
247244
self.checkPermissions()
248245
self.updateMediaKeyTap()

MonitorControl/Support/DisplayManager.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -309,16 +309,18 @@ class DisplayManager {
309309
}
310310
}
311311

312-
func resetSwBrightnessForAllDisplays(settingsOnly: Bool = false, async: Bool = false) {
312+
func resetSwBrightnessForAllDisplays(prefsOnly: Bool = false, noPrefSave: Bool = false, async: Bool = false) {
313313
for otherDisplay in self.getOtherDisplays() {
314-
if !settingsOnly {
315-
_ = otherDisplay.setSwBrightness(1, smooth: async)
316-
otherDisplay.smoothBrightnessTransient = 1
317-
} else {
314+
if !prefsOnly {
315+
_ = otherDisplay.setSwBrightness(1, smooth: async, noPrefSave: noPrefSave)
316+
if !noPrefSave {
317+
otherDisplay.smoothBrightnessTransient = 1
318+
}
319+
} else if !noPrefSave {
318320
otherDisplay.savePref(1, key: .SwBrightness)
319321
otherDisplay.smoothBrightnessTransient = 1
320322
}
321-
if otherDisplay.isSw() {
323+
if otherDisplay.isSw(), !noPrefSave {
322324
otherDisplay.savePref(1, for: .brightness)
323325
}
324326
}
@@ -329,7 +331,7 @@ class DisplayManager {
329331
if (otherDisplay.readPrefAsFloat(for: .brightness) == 0 && !prefs.bool(forKey: PrefKey.disableCombinedBrightness.rawValue)) || (otherDisplay.readPrefAsFloat(for: .brightness) < otherDisplay.combinedBrightnessSwitchingValue() && !prefs.bool(forKey: PrefKey.separateCombinedScale.rawValue) && !prefs.bool(forKey: PrefKey.disableCombinedBrightness.rawValue)) || otherDisplay.isSw() {
330332
let savedPrefValue = otherDisplay.readPrefAsFloat(key: .SwBrightness)
331333
if otherDisplay.getSwBrightness() != savedPrefValue {
332-
OSDUtils.popEmptyOsd(displayID: otherDisplay.identifier, command: Command.brightness) // This will give the user a hint why is the brightness suddenly changes and also give screen activity to counter the 'no gamma change when there is no screen activity' issue on some macs
334+
OSDUtils.popEmptyOsd(displayID: otherDisplay.identifier, command: Command.brightness) // This will give the user a hint why is the brightness suddenly changes.
333335
}
334336
otherDisplay.savePref(otherDisplay.getSwBrightness(), key: .SwBrightness)
335337
os_log("Restoring sw brightness to %{public}@ on other display %{public}@", type: .info, String(savedPrefValue), String(otherDisplay.identifier))

MonitorControl/UI/Base.lproj/Main.storyboard

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1259,7 +1259,7 @@
12591259
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
12601260
<subviews>
12611261
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" tableStyle="inset" selectionHighlightStyle="none" columnReordering="NO" columnResizing="NO" multipleSelection="NO" emptySelection="NO" autosaveColumns="NO" typeSelect="NO" rowHeight="520" viewBased="YES" id="zC9-dS-Tr3">
1262-
<rect key="frame" x="0.0" y="0.0" width="740" height="520"/>
1262+
<rect key="frame" x="0.0" y="0.0" width="740" height="502"/>
12631263
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
12641264
<size key="intercellSpacing" width="14" height="0.0"/>
12651265
<color key="backgroundColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
@@ -2018,7 +2018,7 @@
20182018
<font key="font" metaFont="systemMedium" size="13"/>
20192019
<string key="title">@the0neyouseek (Guillaume B.)
20202020
@JoniVR (Joni Van Roost)
2021-
@waydabber (Istvan T.)</string>
2021+
@waydabber (István T.)</string>
20222022
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
20232023
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
20242024
</textFieldCell>

MonitorControl/UI/de.lproj/Main.strings

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,8 @@
295295
/* Class = "NSTextFieldCell"; title = "General menu items style:"; ObjectID = "thh-DG-ecH"; */
296296
"thh-DG-ecH.title" = "Stil der Menüpunkte:";
297297

298-
/* Class = "NSTextFieldCell"; title = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (Istvan T.)"; ObjectID = "TKd-J8-Iyk"; */
299-
"TKd-J8-Iyk.title" = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (Istvan T.)";
298+
/* Class = "NSTextFieldCell"; title = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (István T.)"; ObjectID = "TKd-J8-Iyk"; */
299+
"TKd-J8-Iyk.title" = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (István T.)";
300300

301301
/* Class = "NSTextFieldCell"; title = "Menu Icon:"; ObjectID = "u6s-Pb-BCG"; */
302302
"u6s-Pb-BCG.title" = "Menü-Symbol:";

MonitorControl/UI/en.lproj/Main.strings

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,8 @@
295295
/* Class = "NSTextFieldCell"; title = "General menu items style:"; ObjectID = "thh-DG-ecH"; */
296296
"thh-DG-ecH.title" = "General menu items style:";
297297

298-
/* Class = "NSTextFieldCell"; title = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (Istvan T.)"; ObjectID = "TKd-J8-Iyk"; */
299-
"TKd-J8-Iyk.title" = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (Istvan T.)";
298+
/* Class = "NSTextFieldCell"; title = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (István T.)"; ObjectID = "TKd-J8-Iyk"; */
299+
"TKd-J8-Iyk.title" = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (István T.)";
300300

301301
/* Class = "NSTextFieldCell"; title = "Menu Icon:"; ObjectID = "u6s-Pb-BCG"; */
302302
"u6s-Pb-BCG.title" = "Menu Icon:";

MonitorControl/UI/fr.lproj/Main.strings

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,8 @@
295295
/* Class = "NSTextFieldCell"; title = "General menu items style:"; ObjectID = "thh-DG-ecH"; */
296296
"thh-DG-ecH.title" = "Style des éléments généraux du menu :";
297297

298-
/* Class = "NSTextFieldCell"; title = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (Istvan T.)"; ObjectID = "TKd-J8-Iyk"; */
299-
"TKd-J8-Iyk.title" = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (Istvan T.)";
298+
/* Class = "NSTextFieldCell"; title = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (István T.)"; ObjectID = "TKd-J8-Iyk"; */
299+
"TKd-J8-Iyk.title" = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (István T.)";
300300

301301
/* Class = "NSTextFieldCell"; title = "Menu Icon:"; ObjectID = "u6s-Pb-BCG"; */
302302
"u6s-Pb-BCG.title" = "Icône du menu :";

MonitorControl/UI/hu.lproj/Main.strings

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,8 @@
295295
/* Class = "NSTextFieldCell"; title = "General menu items style:"; ObjectID = "thh-DG-ecH"; */
296296
"thh-DG-ecH.title" = "Általános menüpontok stílusa:";
297297

298-
/* Class = "NSTextFieldCell"; title = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (Istvan T.)"; ObjectID = "TKd-J8-Iyk"; */
299-
"TKd-J8-Iyk.title" = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (Istvan T.)";
298+
/* Class = "NSTextFieldCell"; title = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (István T.)"; ObjectID = "TKd-J8-Iyk"; */
299+
"TKd-J8-Iyk.title" = "@the0neyouseek (Guillaume B.)\n@JoniVR (Joni Van Roost)\n@waydabber (István T.)";
300300

301301
/* Class = "NSTextFieldCell"; title = "Menu Icon:"; ObjectID = "u6s-Pb-BCG"; */
302302
"u6s-Pb-BCG.title" = "Menü ikon:";

0 commit comments

Comments
 (0)