Tweaks here and there, fixing bugs.

This commit is contained in:
waydabber 2021-08-14 15:33:28 +02:00
parent b129f2f378
commit c17ca676bd
9 changed files with 53 additions and 67 deletions

View file

@ -84,7 +84,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
}
func clearDisplays() {
func clearMenu() {
if self.statusMenu.items.count > 2 {
var items: [NSMenuItem] = []
for i in 0 ..< self.statusMenu.items.count - 2 {
@ -95,9 +95,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
self.statusMenu.removeItem(item)
}
}
self.monitorItems = []
DisplayManager.shared.clearDisplays()
}
func updateArm64AVServices() {
@ -135,7 +133,14 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
}
func updateMenus(controllableExternalDisplays: [ExternalDisplay]) {
func updateMenus() {
self.clearMenu()
var controllableExternalDisplays: [ExternalDisplay] = []
if prefs.bool(forKey: Utils.PrefKeys.fallbackSw.rawValue) {
controllableExternalDisplays = DisplayManager.shared.getNonVirtualExternalDisplays()
} else {
controllableExternalDisplays = DisplayManager.shared.getDdcCapableDisplays()
}
if controllableExternalDisplays.count == 0 {
let item = NSMenuItem()
item.title = NSLocalizedString("No supported display found", comment: "Shown in menu")
@ -161,7 +166,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
os_log("Request for updateDisplay with reconfigreID %{public}@", type: .info, String(dispatchedReconfigureID))
self.reconfigureID = 0
self.clearDisplays()
DisplayManager.shared.clearDisplays()
var onlineDisplayIDs = [CGDirectDisplayID](repeating: 0, count: 10)
var displayCount: UInt32 = 0
guard CGGetOnlineDisplayList(10, &onlineDisplayIDs, &displayCount) == .success else {
@ -195,18 +200,12 @@ class AppDelegate: NSObject, NSApplicationDelegate {
DisplayManager.shared.resetSwBrightnessForAllDisplays(settingsOnly: true)
} else {
if prefs.bool(forKey: Utils.PrefKeys.fallbackSw.rawValue) || prefs.bool(forKey: Utils.PrefKeys.lowerSwAfterBrightness.rawValue) {
DisplayManager.shared.restoreSwBrightnessForAllDisplays()
DisplayManager.shared.restoreSwBrightnessForAllDisplays(async: true)
}
}
self.updateArm64AVServices()
NotificationCenter.default.post(name: Notification.Name(Utils.PrefKeys.displayListUpdate.rawValue), object: nil)
var controllableExternalDisplays: [ExternalDisplay] = []
if prefs.bool(forKey: Utils.PrefKeys.fallbackSw.rawValue) {
controllableExternalDisplays = DisplayManager.shared.getNonVirtualExternalDisplays()
} else {
controllableExternalDisplays = DisplayManager.shared.getDdcCapableDisplays()
}
self.updateMenus(controllableExternalDisplays: controllableExternalDisplays)
self.updateMenus()
}
private func addDisplayToMenu(display: ExternalDisplay, asSubMenu: Bool) {
@ -250,9 +249,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
private func subscribeEventListeners() {
NotificationCenter.default.addObserver(self, selector: #selector(handleListenForChanged), name: .listenFor, object: nil) // subscribe KeyTap event listeners
NotificationCenter.default.addObserver(self, selector: #selector(handleShowContrastChanged), name: .showContrast, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleShowVolumeChanged), name: .showVolume, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleFallbackSwChanged), name: .fallbackSw, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleFriendlyNameChanged), name: .friendlyName, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handlePreferenceReset), name: .preferenceReset, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(audioDeviceChanged), name: Notification.Name.defaultOutputDeviceChanged, object: nil) // subscribe Audio output detector (SimplyCoreAudio)
@ -423,20 +419,8 @@ extension AppDelegate: MediaKeyTapDelegate {
self.updateMediaKeyTap()
}
@objc func handleShowContrastChanged() {
self.updateDisplays()
}
@objc func handleShowVolumeChanged() {
self.updateDisplays()
}
@objc func handleFallbackSwChanged() {
self.updateDisplays()
}
@objc func handleFriendlyNameChanged() {
self.updateDisplays()
self.updateMenus()
}
@objc func handlePreferenceReset() {

View file

@ -3,9 +3,6 @@ import Cocoa
extension NSNotification.Name {
static let accessibilityApi = NSNotification.Name(rawValue: "com.apple.accessibility.api")
static let listenFor = NSNotification.Name(rawValue: Utils.PrefKeys.listenFor.rawValue)
static let showContrast = NSNotification.Name(rawValue: Utils.PrefKeys.showContrast.rawValue)
static let showVolume = NSNotification.Name(rawValue: Utils.PrefKeys.showVolume.rawValue)
static let fallbackSw = NSNotification.Name(rawValue: Utils.PrefKeys.fallbackSw.rawValue)
static let friendlyName = NSNotification.Name(rawValue: Utils.PrefKeys.friendlyName.rawValue)
static let preferenceReset = NSNotification.Name(rawValue: Utils.PrefKeys.preferenceReset.rawValue)
static let displayListUpdate = NSNotification.Name(rawValue: Utils.PrefKeys.displayListUpdate.rawValue)

View file

@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>2240</string>
<string>2305</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>

View file

@ -71,10 +71,10 @@ class DisplayManager {
self.displays = []
}
func resetSwBrightnessForAllDisplays(settingsOnly: Bool = false) {
func resetSwBrightnessForAllDisplays(settingsOnly: Bool = false, async: Bool = false) {
for externalDisplay in self.getNonVirtualExternalDisplays() {
if !settingsOnly {
_ = externalDisplay.setSwBrightness(value: externalDisplay.getSwMaxBrightness())
_ = externalDisplay.setSwBrightness(value: externalDisplay.getSwMaxBrightness(), smooth: async)
} else {
externalDisplay.saveSwBirghtnessPrefValue(Int(externalDisplay.getSwMaxBrightness()))
}
@ -84,12 +84,14 @@ class DisplayManager {
}
}
func restoreSwBrightnessForAllDisplays() {
func restoreSwBrightnessForAllDisplays(async: Bool = false) {
for externalDisplay in self.getExternalDisplays() {
if externalDisplay.getValue(for: .brightness) == 0 || externalDisplay.isSw() {
_ = externalDisplay.setSwBrightness(value: UInt8(externalDisplay.getSwBrightnessPrefValue()))
let savedPrefValue = externalDisplay.getSwBrightnessPrefValue()
externalDisplay.saveSwBirghtnessPrefValue(Int(externalDisplay.getSwBrightness()))
_ = externalDisplay.setSwBrightness(value: UInt8(savedPrefValue), smooth: async)
} else {
_ = externalDisplay.setSwBrightness(value: externalDisplay.getSwMaxBrightness())
_ = externalDisplay.setSwBrightness(value: externalDisplay.getSwMaxBrightness(), smooth: async)
}
}
}

View file

@ -93,28 +93,36 @@ class Display {
}
}
func setSwBrightness(value: UInt8, fast _: Bool = false) -> Bool {
let swBrightnessSemaphore = DispatchSemaphore(value: 1)
func setSwBrightness(value: UInt8, smooth: Bool = false) -> Bool {
let brightnessValue: UInt8 = min(getSwMaxBrightness(), value)
var currentValue = Float(self.getSwBrightness()) / Float(self.getSwMaxBrightness())
// var currentValue = Float(self.getSwBrightnessPrefValue()) / Float(self.getSwMaxBrightness()) // Better for async version but is not right after display reconfiguration
var currentValue = Float(self.getSwBrightnessPrefValue()) / Float(self.getSwMaxBrightness())
self.saveSwBirghtnessPrefValue(Int(brightnessValue))
var newValue = Float(Float(brightnessValue)) / Float(self.getSwMaxBrightness())
currentValue = self.swBrightnessTransform(value: currentValue)
newValue = self.swBrightnessTransform(value: newValue)
os_log("setting software brightness to: %{public}@", type: .debug, String(newValue))
let gammaTableRed = self.defaultGammaTableRed.map { $0 * /* transientValue */ newValue }
let gammaTableGreen = self.defaultGammaTableGreen.map { $0 * /* transientValue */ newValue }
let gammaTableBlue = self.defaultGammaTableBlue.map { $0 * /* transientValue */ newValue }
CGSetDisplayTransferByTable(self.identifier, self.defaultGammaTableSampleCount, gammaTableRed, gammaTableGreen, gammaTableBlue)
// DispatchQueue.global(qos: .userInitiated).async {
// for transientValue in stride(from: currentValue, to: newValue, by: 0.0025 * (currentValue > newValue ? -1 : 1)) {
// let gammaTableRed = self.defaultGammaTableRed.map { $0 * transientValue }
// let gammaTableGreen = self.defaultGammaTableGreen.map { $0 * transientValue }
// let gammaTableBlue = self.defaultGammaTableBlue.map { $0 * transientValue }
// CGSetDisplayTransferByTable(self.identifier, self.defaultGammaTableSampleCount, gammaTableRed, gammaTableGreen, gammaTableBlue)
// Thread.sleep(forTimeInterval: 0.0005) // This will make things a bit nicer and mimic delay of DDC communication for consistency
// }
// }
if smooth {
DispatchQueue.global(qos: .userInteractive).async {
self.swBrightnessSemaphore.wait()
for transientValue in stride(from: currentValue, to: newValue, by: 0.0025 * (currentValue > newValue ? -1 : 1)) {
let gammaTableRed = self.defaultGammaTableRed.map { $0 * transientValue }
let gammaTableGreen = self.defaultGammaTableGreen.map { $0 * transientValue }
let gammaTableBlue = self.defaultGammaTableBlue.map { $0 * transientValue }
guard app.reconfigureID == 0 else {
return
}
CGSetDisplayTransferByTable(self.identifier, self.defaultGammaTableSampleCount, gammaTableRed, gammaTableGreen, gammaTableBlue)
Thread.sleep(forTimeInterval: 0.001) // Let's make things quick if not performed in the background
}
self.swBrightnessSemaphore.signal()
}
} else {
let gammaTableRed = self.defaultGammaTableRed.map { $0 * /* transientValue */ newValue }
let gammaTableGreen = self.defaultGammaTableGreen.map { $0 * /* transientValue */ newValue }
let gammaTableBlue = self.defaultGammaTableBlue.map { $0 * /* transientValue */ newValue }
CGSetDisplayTransferByTable(self.identifier, self.defaultGammaTableSampleCount, gammaTableRed, gammaTableGreen, gammaTableBlue)
}
return true
}

View file

@ -168,7 +168,7 @@ class ExternalDisplay: Display {
let isAlreadySet = osdValue == self.getValue(for: .brightness)
if self.isSw(), self.prefs.bool(forKey: Utils.PrefKeys.fallbackSw.rawValue) {
if self.setSwBrightness(value: UInt8(osdValue)) {
if self.setSwBrightness(value: UInt8(osdValue), smooth: true) {
self.showOsd(command: .brightness, value: osdValue, roundChiclet: !isSmallIncrement)
self.saveValue(osdValue, for: .brightness)
if let slider = brightnessSliderHandler?.slider {
@ -192,7 +192,7 @@ class ExternalDisplay: Display {
swBirghtnessValue = Int(getSwMaxBrightness())
swAfterBirghtnessMode = false
}
if self.setSwBrightness(value: UInt8(swBirghtnessValue), fast: true) {
if self.setSwBrightness(value: UInt8(swBirghtnessValue), smooth: true) {
self.showOsd(command: .brightness, value: self.getValue(for: .brightness), roundChiclet: !isSmallIncrement)
}
}

View file

@ -66,7 +66,7 @@ class Utils: NSObject {
var (currentValue, maxValue) = (UInt16(0), UInt16(0))
if display.isSw(), command == DDC.Command.brightness {
(currentValue, maxValue) = (UInt16(display.getSwBrightness()), UInt16(display.getSwMaxBrightness()))
(currentValue, maxValue) = (UInt16(display.getSwBrightnessPrefValue()), UInt16(display.getSwMaxBrightness()))
} else {
if tries != 0 {
values = display.readDDCValues(for: command, tries: tries, minReplyDelay: delay)

View file

@ -89,12 +89,10 @@ class MainPrefsViewController: NSViewController, PreferencePane {
self.prefs.set(false, forKey: Utils.PrefKeys.showContrast.rawValue)
default: break
}
app.updateMenus()
#if DEBUG
os_log("Toggle show contrast slider state: %{public}@", type: .info, sender.state == .on ? "on" : "off")
#endif
NotificationCenter.default.post(name: Notification.Name(Utils.PrefKeys.showContrast.rawValue), object: nil)
}
@IBAction func showVolumeSliderClicked(_ sender: NSButton) {
@ -105,12 +103,10 @@ class MainPrefsViewController: NSViewController, PreferencePane {
self.prefs.set(false, forKey: Utils.PrefKeys.showVolume.rawValue)
default: break
}
app.updateMenus()
#if DEBUG
os_log("Toggle show volume slider state: %{public}@", type: .info, sender.state == .on ? "on" : "off")
#endif
NotificationCenter.default.post(name: Notification.Name(Utils.PrefKeys.showVolume.rawValue), object: nil)
}
@IBAction func lowerSwAfterBrightnessClicked(_ sender: NSButton) {
@ -133,14 +129,13 @@ class MainPrefsViewController: NSViewController, PreferencePane {
self.prefs.set(true, forKey: Utils.PrefKeys.fallbackSw.rawValue)
case .off:
self.prefs.set(false, forKey: Utils.PrefKeys.fallbackSw.rawValue)
DisplayManager.shared.resetSwBrightnessForAllDisplays()
default: break
}
DisplayManager.shared.resetSwBrightnessForAllDisplays()
app.updateMenus()
#if DEBUG
os_log("Toggle fallback to software if no DDC: %{public}@", type: .info, sender.state == .on ? "on" : "off")
#endif
NotificationCenter.default.post(name: Notification.Name(Utils.PrefKeys.fallbackSw.rawValue), object: nil)
}
@IBAction func listenForChanged(_ sender: NSPopUpButton) {

View file

@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>2240</string>
<string>2305</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSBackgroundOnly</key>