mirror of
https://github.com/MonitorControl/MonitorControl.git
synced 2026-05-21 06:46:18 -06:00
Some additional fixes (#738)
- Fix naming of wakeNotification() - Fix for failing to update Advanced Settings checkbox on Preferences Reset. - Better handling of known dummy displays.
This commit is contained in:
parent
5d3d08ddfc
commit
6248d582ac
10 changed files with 70 additions and 26 deletions
|
|
@ -19,7 +19,7 @@
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>$(MARKETING_VERSION)</string>
|
<string>$(MARKETING_VERSION)</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>6828</string>
|
<string>6850</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.utilities</string>
|
<string>public.app-category.utilities</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,24 @@ import os.log
|
||||||
class AppleDisplay: Display {
|
class AppleDisplay: Display {
|
||||||
private var displayQueue: DispatchQueue
|
private var displayQueue: DispatchQueue
|
||||||
|
|
||||||
override init(_ identifier: CGDirectDisplayID, name: String, vendorNumber: UInt32?, modelNumber: UInt32?, isVirtual: Bool = false) {
|
override init(_ identifier: CGDirectDisplayID, name: String, vendorNumber: UInt32?, modelNumber: UInt32?, isVirtual: Bool = false, isDummy: Bool = false) {
|
||||||
self.displayQueue = DispatchQueue(label: String("displayQueue-\(identifier)"))
|
self.displayQueue = DispatchQueue(label: String("displayQueue-\(identifier)"))
|
||||||
super.init(identifier, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, isVirtual: isVirtual)
|
super.init(identifier, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, isVirtual: isVirtual, isDummy: isDummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getAppleBrightness() -> Float {
|
public func getAppleBrightness() -> Float {
|
||||||
|
guard !self.isDummy else {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
var brightness: Float = 0
|
var brightness: Float = 0
|
||||||
DisplayServicesGetBrightness(self.identifier, &brightness)
|
DisplayServicesGetBrightness(self.identifier, &brightness)
|
||||||
return brightness
|
return brightness
|
||||||
}
|
}
|
||||||
|
|
||||||
public func setAppleBrightness(value: Float) {
|
public func setAppleBrightness(value: Float) {
|
||||||
|
guard !self.isDummy else {
|
||||||
|
return
|
||||||
|
}
|
||||||
self.displayQueue.sync {
|
self.displayQueue.sync {
|
||||||
DisplayServicesSetBrightness(self.identifier, value)
|
DisplayServicesSetBrightness(self.identifier, value)
|
||||||
DisplayServicesBrightnessChanged(self.identifier, Double(value))
|
DisplayServicesBrightnessChanged(self.identifier, Double(value))
|
||||||
|
|
@ -25,6 +31,9 @@ class AppleDisplay: Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func setDirectBrightness(_ to: Float, transient: Bool = false) -> Bool {
|
override func setDirectBrightness(_ to: Float, transient: Bool = false) -> Bool {
|
||||||
|
guard !self.isDummy else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
let value = max(min(to, 1), 0)
|
let value = max(min(to, 1), 0)
|
||||||
self.setAppleBrightness(value: value)
|
self.setAppleBrightness(value: value)
|
||||||
if !transient {
|
if !transient {
|
||||||
|
|
@ -36,6 +45,9 @@ class AppleDisplay: Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func getBrightness() -> Float {
|
override func getBrightness() -> Float {
|
||||||
|
guard !self.isDummy else {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
if self.prefExists(for: .brightness) {
|
if self.prefExists(for: .brightness) {
|
||||||
return self.readPrefAsFloat(for: .brightness)
|
return self.readPrefAsFloat(for: .brightness)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ class Display: Equatable {
|
||||||
var sliderHandler: [Command: SliderHandler] = [:]
|
var sliderHandler: [Command: SliderHandler] = [:]
|
||||||
var brightnessSyncSourceValue: Float = 1
|
var brightnessSyncSourceValue: Float = 1
|
||||||
var isVirtual: Bool = false
|
var isVirtual: Bool = false
|
||||||
|
var isDummy: Bool = false
|
||||||
|
|
||||||
var defaultGammaTableRed = [CGGammaValue](repeating: 0, count: 256)
|
var defaultGammaTableRed = [CGGammaValue](repeating: 0, count: 256)
|
||||||
var defaultGammaTableGreen = [CGGammaValue](repeating: 0, count: 256)
|
var defaultGammaTableGreen = [CGGammaValue](repeating: 0, count: 256)
|
||||||
|
|
@ -61,7 +62,7 @@ class Display: Equatable {
|
||||||
return (key ?? PrefKey.value).rawValue + (command != nil ? String((command ?? Command.none).rawValue) : "") + self.prefsId
|
return (key ?? PrefKey.value).rawValue + (command != nil ? String((command ?? Command.none).rawValue) : "") + self.prefsId
|
||||||
}
|
}
|
||||||
|
|
||||||
internal init(_ identifier: CGDirectDisplayID, name: String, vendorNumber: UInt32?, modelNumber: UInt32?, isVirtual: Bool = false) {
|
internal init(_ identifier: CGDirectDisplayID, name: String, vendorNumber: UInt32?, modelNumber: UInt32?, isVirtual: Bool = false, isDummy: Bool = false) {
|
||||||
self.identifier = identifier
|
self.identifier = identifier
|
||||||
self.name = name
|
self.name = name
|
||||||
self.vendorNumber = vendorNumber
|
self.vendorNumber = vendorNumber
|
||||||
|
|
@ -69,13 +70,14 @@ class Display: Equatable {
|
||||||
self.prefsId = "(" + String(name.filter { !$0.isWhitespace }) + String(vendorNumber ?? 0) + String(modelNumber ?? 0) + "@" + String(identifier) + ")"
|
self.prefsId = "(" + String(name.filter { !$0.isWhitespace }) + String(vendorNumber ?? 0) + String(modelNumber ?? 0) + "@" + String(identifier) + ")"
|
||||||
os_log("Display init with prefsIdentifier %{public}@", type: .info, self.prefsId)
|
os_log("Display init with prefsIdentifier %{public}@", type: .info, self.prefsId)
|
||||||
self.isVirtual = DEBUG_VIRTUAL ? true : isVirtual
|
self.isVirtual = DEBUG_VIRTUAL ? true : isVirtual
|
||||||
|
self.isDummy = isDummy
|
||||||
self.swUpdateDefaultGammaTable()
|
self.swUpdateDefaultGammaTable()
|
||||||
self.smoothBrightnessTransient = self.getBrightness()
|
self.smoothBrightnessTransient = self.getBrightness()
|
||||||
if self.isVirtual {
|
if self.isVirtual || self.readPrefAsBool(key: PrefKey.avoidGamma), !self.isDummy {
|
||||||
os_log("Creating or updating shade for virtual display %{public}@", type: .info, String(self.identifier))
|
os_log("Creating or updating shade for display %{public}@", type: .info, String(self.identifier))
|
||||||
_ = DisplayManager.shared.updateShade(displayID: self.identifier)
|
_ = DisplayManager.shared.updateShade(displayID: self.identifier)
|
||||||
} else {
|
} else {
|
||||||
os_log("Destroying shade (if exists) for real display %{public}@", type: .info, String(self.identifier))
|
os_log("Destroying shade (if exists) for display %{public}@", type: .info, String(self.identifier))
|
||||||
_ = DisplayManager.shared.destroyShade(displayID: self.identifier)
|
_ = DisplayManager.shared.destroyShade(displayID: self.identifier)
|
||||||
}
|
}
|
||||||
self.brightnessSyncSourceValue = self.getBrightness()
|
self.brightnessSyncSourceValue = self.getBrightness()
|
||||||
|
|
@ -187,6 +189,9 @@ class Display: Equatable {
|
||||||
}
|
}
|
||||||
|
|
||||||
func swUpdateDefaultGammaTable() {
|
func swUpdateDefaultGammaTable() {
|
||||||
|
guard !self.isDummy else {
|
||||||
|
return
|
||||||
|
}
|
||||||
CGGetDisplayTransferByTable(self.identifier, 256, &self.defaultGammaTableRed, &self.defaultGammaTableGreen, &self.defaultGammaTableBlue, &self.defaultGammaTableSampleCount)
|
CGGetDisplayTransferByTable(self.identifier, 256, &self.defaultGammaTableRed, &self.defaultGammaTableGreen, &self.defaultGammaTableBlue, &self.defaultGammaTableSampleCount)
|
||||||
let redPeak = self.defaultGammaTableRed.max() ?? 0
|
let redPeak = self.defaultGammaTableRed.max() ?? 0
|
||||||
let greenPeak = self.defaultGammaTableGreen.max() ?? 0
|
let greenPeak = self.defaultGammaTableGreen.max() ?? 0
|
||||||
|
|
@ -210,6 +215,10 @@ class Display: Equatable {
|
||||||
if !noPrefSave {
|
if !noPrefSave {
|
||||||
self.savePref(brightnessValue, key: .SwBrightness)
|
self.savePref(brightnessValue, key: .SwBrightness)
|
||||||
}
|
}
|
||||||
|
guard !self.isDummy else {
|
||||||
|
self.swBrightnessSemaphore.signal()
|
||||||
|
return true
|
||||||
|
}
|
||||||
var newValue = brightnessValue
|
var newValue = brightnessValue
|
||||||
currentValue = self.swBrightnessTransform(value: currentValue)
|
currentValue = self.swBrightnessTransform(value: currentValue)
|
||||||
newValue = self.swBrightnessTransform(value: newValue)
|
newValue = self.swBrightnessTransform(value: newValue)
|
||||||
|
|
@ -249,6 +258,13 @@ class Display: Equatable {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSwBrightness() -> Float {
|
func getSwBrightness() -> Float {
|
||||||
|
guard !self.isDummy else {
|
||||||
|
if self.prefExists(key: .SwBrightness) {
|
||||||
|
return self.readPrefAsFloat(key: .SwBrightness)
|
||||||
|
} else {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
self.swBrightnessSemaphore.wait()
|
self.swBrightnessSemaphore.wait()
|
||||||
if self.isVirtual || self.readPrefAsBool(key: .avoidGamma) {
|
if self.isVirtual || self.readPrefAsBool(key: .avoidGamma) {
|
||||||
let rawBrightnessValue = 1 - (DisplayManager.shared.getShadeAlpha(displayID: self.identifier) ?? 1)
|
let rawBrightnessValue = 1 - (DisplayManager.shared.getShadeAlpha(displayID: self.identifier) ?? 1)
|
||||||
|
|
@ -274,7 +290,7 @@ class Display: Equatable {
|
||||||
|
|
||||||
func checkGammaInterference() {
|
func checkGammaInterference() {
|
||||||
let currentSwBrightness = self.getSwBrightness()
|
let currentSwBrightness = self.getSwBrightness()
|
||||||
guard !DisplayManager.shared.gammaInterferenceWarningShown, !(prefs.bool(forKey: PrefKey.disableCombinedBrightness.rawValue)), !self.readPrefAsBool(key: .avoidGamma), !self.isVirtual, !self.smoothBrightnessRunning, self.prefExists(key: .SwBrightness), abs(currentSwBrightness - self.readPrefAsFloat(key: .SwBrightness)) > 0.02 else {
|
guard !self.isDummy, !DisplayManager.shared.gammaInterferenceWarningShown, !(prefs.bool(forKey: PrefKey.disableCombinedBrightness.rawValue)), !self.readPrefAsBool(key: .avoidGamma), !self.isVirtual, !self.smoothBrightnessRunning, self.prefExists(key: .SwBrightness), abs(currentSwBrightness - self.readPrefAsFloat(key: .SwBrightness)) > 0.02 else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
DisplayManager.shared.gammaInterferenceCounter += 1
|
DisplayManager.shared.gammaInterferenceCounter += 1
|
||||||
|
|
@ -309,7 +325,7 @@ class Display: Equatable {
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSwBrightnessNotDefault() -> Bool {
|
func isSwBrightnessNotDefault() -> Bool {
|
||||||
guard !self.isVirtual else {
|
guard !self.isVirtual, !self.isDummy else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if self.getSwBrightness() < 1 {
|
if self.getSwBrightness() < 1 {
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ class OtherDisplay: Display {
|
||||||
set { prefs.set(newValue, forKey: PrefKey.pollingCount.rawValue + self.prefsId) }
|
set { prefs.set(newValue, forKey: PrefKey.pollingCount.rawValue + self.prefsId) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override init(_ identifier: CGDirectDisplayID, name: String, vendorNumber: UInt32?, modelNumber: UInt32?, isVirtual: Bool = false) {
|
override init(_ identifier: CGDirectDisplayID, name: String, vendorNumber: UInt32?, modelNumber: UInt32?, isVirtual: Bool = false, isDummy: Bool = false) {
|
||||||
super.init(identifier, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, isVirtual: isVirtual)
|
super.init(identifier, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, isVirtual: isVirtual, isDummy: isDummy)
|
||||||
if !isVirtual, !Arm64DDC.isArm64 {
|
if !isVirtual, !Arm64DDC.isArm64 {
|
||||||
self.ddc = IntelDDC(for: identifier)
|
self.ddc = IntelDDC(for: identifier)
|
||||||
}
|
}
|
||||||
|
|
@ -256,7 +256,7 @@ class OtherDisplay: Display {
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSwOnly() -> Bool {
|
func isSwOnly() -> Bool {
|
||||||
return (!self.arm64ddc && self.ddc == nil) || self.isVirtual
|
return (!self.arm64ddc && self.ddc == nil) || self.isVirtual || self.isDummy
|
||||||
}
|
}
|
||||||
|
|
||||||
func isSw() -> Bool {
|
func isSw() -> Bool {
|
||||||
|
|
|
||||||
|
|
@ -168,9 +168,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(self.audioDeviceChanged), name: Notification.Name.defaultOutputDeviceChanged, object: nil) // subscribe Audio output detector (SimplyCoreAudio)
|
NotificationCenter.default.addObserver(self, selector: #selector(self.audioDeviceChanged), name: Notification.Name.defaultOutputDeviceChanged, object: nil) // subscribe Audio output detector (SimplyCoreAudio)
|
||||||
DistributedNotificationCenter.default.addObserver(self, selector: #selector(self.displayReconfigured), name: NSNotification.Name(rawValue: kColorSyncDisplayDeviceProfilesNotification.takeRetainedValue() as String), object: nil) // ColorSync change
|
DistributedNotificationCenter.default.addObserver(self, selector: #selector(self.displayReconfigured), name: NSNotification.Name(rawValue: kColorSyncDisplayDeviceProfilesNotification.takeRetainedValue() as String), object: nil) // ColorSync change
|
||||||
NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.sleepNotification), name: NSWorkspace.screensDidSleepNotification, object: nil) // sleep and wake listeners
|
NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.sleepNotification), name: NSWorkspace.screensDidSleepNotification, object: nil) // sleep and wake listeners
|
||||||
NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.wakeNotofication), name: NSWorkspace.screensDidWakeNotification, object: nil)
|
NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.wakeNotification), name: NSWorkspace.screensDidWakeNotification, object: nil)
|
||||||
NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.sleepNotification), name: NSWorkspace.willSleepNotification, object: nil)
|
NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.sleepNotification), name: NSWorkspace.willSleepNotification, object: nil)
|
||||||
NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.wakeNotofication), name: NSWorkspace.didWakeNotification, object: nil)
|
NSWorkspace.shared.notificationCenter.addObserver(self, selector: #selector(self.wakeNotification), name: NSWorkspace.didWakeNotification, object: nil)
|
||||||
_ = DistributedNotificationCenter.default().addObserver(forName: NSNotification.Name(rawValue: NSNotification.Name.accessibilityApi.rawValue), object: nil, queue: nil) { _ in DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.updateMediaKeyTap() } } // listen for accessibility status changes
|
_ = DistributedNotificationCenter.default().addObserver(forName: NSNotification.Name(rawValue: NSNotification.Name.accessibilityApi.rawValue), object: nil, queue: nil) { _ in DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { self.updateMediaKeyTap() } } // listen for accessibility status changes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,7 +179,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
os_log("Sleeping with sleep %{public}@", type: .info, String(self.sleepID))
|
os_log("Sleeping with sleep %{public}@", type: .info, String(self.sleepID))
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func wakeNotofication() {
|
@objc private func wakeNotification() {
|
||||||
if self.sleepID != 0 {
|
if self.sleepID != 0 {
|
||||||
os_log("Waking up from sleep %{public}@", type: .info, String(self.sleepID))
|
os_log("Waking up from sleep %{public}@", type: .info, String(self.sleepID))
|
||||||
let dispatchedSleepID = self.sleepID
|
let dispatchedSleepID = self.sleepID
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,10 @@ class Arm64DDC: NSObject {
|
||||||
if ioregService.manufacturerID == "AOC", ioregService.productName == "28E850" {
|
if ioregService.manufacturerID == "AOC", ioregService.productName == "28E850" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
// If the display contains the string "Dummy", then it is highly suspicious
|
||||||
|
if ioregService.productName.contains("Dummy") || ioregService.productName.contains("dummy") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
// First service location of Mac Mini HDMI is broken for DDC communication
|
// First service location of Mac Mini HDMI is broken for DDC communication
|
||||||
if ioregService.transportDownstream == "HDMI", ioregService.serviceLocation == 1, modelIdentifier == "Macmini9,1" {
|
if ioregService.transportDownstream == "HDMI", ioregService.serviceLocation == 1, modelIdentifier == "Macmini9,1" {
|
||||||
return true
|
return true
|
||||||
|
|
|
||||||
|
|
@ -151,27 +151,34 @@ class DisplayManager {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for onlineDisplayID in onlineDisplayIDs where onlineDisplayID != 0 {
|
for onlineDisplayID in onlineDisplayIDs where onlineDisplayID != 0 {
|
||||||
|
let rawName = DisplayManager.getDisplayRawNameByID(displayID: onlineDisplayID)
|
||||||
let name = DisplayManager.getDisplayNameByID(displayID: onlineDisplayID)
|
let name = DisplayManager.getDisplayNameByID(displayID: onlineDisplayID)
|
||||||
let id = onlineDisplayID
|
let id = onlineDisplayID
|
||||||
let vendorNumber = CGDisplayVendorNumber(onlineDisplayID)
|
let vendorNumber = CGDisplayVendorNumber(onlineDisplayID)
|
||||||
let modelNumber = CGDisplayModelNumber(onlineDisplayID)
|
let modelNumber = CGDisplayModelNumber(onlineDisplayID)
|
||||||
|
var isDummy: Bool = false
|
||||||
var isVirtual: Bool = false
|
var isVirtual: Bool = false
|
||||||
|
if rawName == "28E850" || rawName.lowercased().contains("dummy") {
|
||||||
|
os_log("NOTE: Display is a dummy!", type: .info)
|
||||||
|
isDummy = true
|
||||||
|
}
|
||||||
if !DEBUG_MACOS10, #available(macOS 11.0, *) {
|
if !DEBUG_MACOS10, #available(macOS 11.0, *) {
|
||||||
if let dictionary = ((CoreDisplay_DisplayCreateInfoDictionary(onlineDisplayID))?.takeRetainedValue() as NSDictionary?) {
|
if let dictionary = ((CoreDisplay_DisplayCreateInfoDictionary(onlineDisplayID))?.takeRetainedValue() as NSDictionary?) {
|
||||||
let isVirtualDevice = dictionary["kCGDisplayIsVirtualDevice"] as? Bool
|
let isVirtualDevice = dictionary["kCGDisplayIsVirtualDevice"] as? Bool
|
||||||
let displayIsAirplay = dictionary["kCGDisplayIsAirPlay"] as? Bool
|
let displayIsAirplay = dictionary["kCGDisplayIsAirPlay"] as? Bool
|
||||||
if isVirtualDevice ?? displayIsAirplay ?? false {
|
if isVirtualDevice ?? displayIsAirplay ?? false {
|
||||||
|
os_log("NOTE: Display is virtual!", type: .info)
|
||||||
isVirtual = true
|
isVirtual = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !DEBUG_SW, DisplayManager.isAppleDisplay(displayID: onlineDisplayID) { // MARK: (point of interest for testing)
|
if !DEBUG_SW, DisplayManager.isAppleDisplay(displayID: onlineDisplayID) { // MARK: (point of interest for testing)
|
||||||
let appleDisplay = AppleDisplay(id, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, isVirtual: isVirtual)
|
let appleDisplay = AppleDisplay(id, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, isVirtual: isVirtual, isDummy: isDummy)
|
||||||
os_log("Apple display found - %{public}@", type: .info, "ID: \(appleDisplay.identifier) Name: \(appleDisplay.name) (Vendor: \(appleDisplay.vendorNumber ?? 0), Model: \(appleDisplay.modelNumber ?? 0))")
|
os_log("Apple display found - %{public}@", type: .info, "ID: \(appleDisplay.identifier), Name: \(appleDisplay.name) (Vendor: \(appleDisplay.vendorNumber ?? 0), Model: \(appleDisplay.modelNumber ?? 0))")
|
||||||
self.addDisplay(display: appleDisplay)
|
self.addDisplay(display: appleDisplay)
|
||||||
} else {
|
} else {
|
||||||
let otherDisplay = OtherDisplay(id, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, isVirtual: isVirtual)
|
let otherDisplay = OtherDisplay(id, name: name, vendorNumber: vendorNumber, modelNumber: modelNumber, isVirtual: isVirtual, isDummy: isDummy)
|
||||||
os_log("Other display found - %{public}@", type: .info, "ID: \(otherDisplay.identifier) Name: \(otherDisplay.name) (Vendor: \(otherDisplay.vendorNumber ?? 0), Model: \(otherDisplay.modelNumber ?? 0))")
|
os_log("Other display found - %{public}@", type: .info, "ID: \(otherDisplay.identifier), Name: \(otherDisplay.name) (Vendor: \(otherDisplay.vendorNumber ?? 0), Model: \(otherDisplay.modelNumber ?? 0))")
|
||||||
self.addDisplay(display: otherDisplay)
|
self.addDisplay(display: otherDisplay)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -351,7 +358,7 @@ class DisplayManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAffectedDisplays(isBrightness: Bool = false, isVolume: Bool = false, isContrast _: Bool = false) -> [Display]? {
|
func getAffectedDisplays(isBrightness: Bool = false, isVolume: Bool = false) -> [Display]? {
|
||||||
var affectedDisplays: [Display]
|
var affectedDisplays: [Display]
|
||||||
let allDisplays = self.getAllDisplays()
|
let allDisplays = self.getAllDisplays()
|
||||||
var currentDisplay: Display?
|
var currentDisplay: Display?
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,13 @@ class DisplaysPrefsViewController: NSViewController, PreferencePane, NSTableView
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
self.showAdvancedDisplays.state = prefs.bool(forKey: PrefKey.showAdvancedSettings.rawValue) ? .on : .off
|
|
||||||
self.loadDisplayList()
|
|
||||||
self.displayScrollView.scrollerStyle = .legacy
|
self.displayScrollView.scrollerStyle = .legacy
|
||||||
|
self.populateSettings()
|
||||||
|
self.loadDisplayList()
|
||||||
|
}
|
||||||
|
|
||||||
|
func populateSettings() {
|
||||||
|
self.showAdvancedDisplays.state = prefs.bool(forKey: PrefKey.showAdvancedSettings.rawValue) ? .on : .off
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear() {
|
override func viewWillAppear() {
|
||||||
|
|
@ -88,12 +92,12 @@ class DisplaysPrefsViewController: NSViewController, PreferencePane, NSTableView
|
||||||
var displayImage = "display.trianglebadge.exclamationmark"
|
var displayImage = "display.trianglebadge.exclamationmark"
|
||||||
var controlMethod = NSLocalizedString("No Control", comment: "Shown in the Display Preferences") + " ⚠️"
|
var controlMethod = NSLocalizedString("No Control", comment: "Shown in the Display Preferences") + " ⚠️"
|
||||||
var controlStatus = NSLocalizedString("This display has an unspecified control status.", comment: "Shown in the Display Preferences")
|
var controlStatus = NSLocalizedString("This display has an unspecified control status.", comment: "Shown in the Display Preferences")
|
||||||
if display.isVirtual {
|
if display.isVirtual, !display.isDummy {
|
||||||
displayType = NSLocalizedString("Virtual Display", comment: "Shown in the Display Preferences")
|
displayType = NSLocalizedString("Virtual Display", comment: "Shown in the Display Preferences")
|
||||||
displayImage = "tv.and.mediabox"
|
displayImage = "tv.and.mediabox"
|
||||||
controlMethod = NSLocalizedString("Software (shade)", comment: "Shown in the Display Preferences") + " ⚠️"
|
controlMethod = NSLocalizedString("Software (shade)", comment: "Shown in the Display Preferences") + " ⚠️"
|
||||||
controlStatus = NSLocalizedString("This is a virtual display (examples: AirPlay, Sidecar, display connected via a DisplayLink Dock or similar) which does not allow hardware or software gammatable control. Shading is used as a substitute but only in non-mirror scenarios. Mouse cursor will be unaffected and artifacts may appear when entering/leaving full screen mode.", comment: "Shown in the Display Preferences")
|
controlStatus = NSLocalizedString("This is a virtual display (examples: AirPlay, Sidecar, display connected via a DisplayLink Dock or similar) which does not allow hardware or software gammatable control. Shading is used as a substitute but only in non-mirror scenarios. Mouse cursor will be unaffected and artifacts may appear when entering/leaving full screen mode.", comment: "Shown in the Display Preferences")
|
||||||
} else if display is OtherDisplay {
|
} else if display is OtherDisplay, !display.isDummy {
|
||||||
displayType = NSLocalizedString("External Display", comment: "Shown in the Display Preferences")
|
displayType = NSLocalizedString("External Display", comment: "Shown in the Display Preferences")
|
||||||
displayImage = "display"
|
displayImage = "display"
|
||||||
if let otherDisplay: OtherDisplay = display as? OtherDisplay {
|
if let otherDisplay: OtherDisplay = display as? OtherDisplay {
|
||||||
|
|
@ -119,7 +123,7 @@ class DisplaysPrefsViewController: NSViewController, PreferencePane, NSTableView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let appleDisplay: AppleDisplay = display as? AppleDisplay {
|
} else if !display.isDummy, let appleDisplay: AppleDisplay = display as? AppleDisplay {
|
||||||
if appleDisplay.isBuiltIn() {
|
if appleDisplay.isBuiltIn() {
|
||||||
displayType = NSLocalizedString("Built-in Display", comment: "Shown in the Display Preferences")
|
displayType = NSLocalizedString("Built-in Display", comment: "Shown in the Display Preferences")
|
||||||
if self.isImac() {
|
if self.isImac() {
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ class MainPrefsViewController: NSViewController, PreferencePane {
|
||||||
self.populateSettings()
|
self.populateSettings()
|
||||||
menuslidersPrefsVc?.populateSettings()
|
menuslidersPrefsVc?.populateSettings()
|
||||||
keyboardPrefsVc?.populateSettings()
|
keyboardPrefsVc?.populateSettings()
|
||||||
|
displaysPrefsVc?.populateSettings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>$(MARKETING_VERSION)</string>
|
<string>$(MARKETING_VERSION)</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>6828</string>
|
<string>6850</string>
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.utilities</string>
|
<string>public.app-category.utilities</string>
|
||||||
<key>LSBackgroundOnly</key>
|
<key>LSBackgroundOnly</key>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue