diff --git a/MonitorControl/Info.plist b/MonitorControl/Info.plist index 3537c98..85621d8 100644 --- a/MonitorControl/Info.plist +++ b/MonitorControl/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion - 6956 + 6957 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/MonitorControl/Support/Arm64DDC.swift b/MonitorControl/Support/Arm64DDC.swift index c08ae7f..2ac3855 100644 --- a/MonitorControl/Support/Arm64DDC.swift +++ b/MonitorControl/Support/Arm64DDC.swift @@ -9,6 +9,7 @@ class Arm64DDC: NSObject { var service: IOAVService? var serviceLocation: Int = 0 var isDiscouraged: Bool = false + var isDummy: Bool = false } #if arch(arm64) @@ -26,7 +27,8 @@ class Arm64DDC: NSObject { for ioregServiceForMatching in ioregServicesForMatching { let score = self.ioregMatchScore(displayID: displayID, ioregEdidUUID: ioregServiceForMatching.edidUUID, ioregProductName: ioregServiceForMatching.productName, ioregSerialNumber: ioregServiceForMatching.serialNumber, serviceLocation: ioregServiceForMatching.serviceLocation) let isDiscouraged = self.checkIfDiscouraged(ioregService: ioregServiceForMatching) - let displayService = DisplayService(displayID: displayID, service: ioregServiceForMatching.service, serviceLocation: ioregServiceForMatching.serviceLocation, isDiscouraged: isDiscouraged) + let isDummy = self.checkIfDummy(ioregService: ioregServiceForMatching) + let displayService = DisplayService(displayID: displayID, service: ioregServiceForMatching.service, serviceLocation: ioregServiceForMatching.serviceLocation, isDiscouraged: isDiscouraged, isDummy: isDummy) if scoredCandidateDisplayServices[score] == nil { scoredCandidateDisplayServices[score] = [] } @@ -260,6 +262,15 @@ class Arm64DDC: NSObject { return ioregServicesForMatching } + // Check if display is a dummy + private static func checkIfDummy(ioregService: IOregService) -> Bool { + // This is a well known dummy plug + if ioregService.manufacturerID == "AOC", ioregService.productName == "28E850" { + return true + } + return false + } + // Check if it is problematic to enable DDC on the display private static func checkIfDiscouraged(ioregService: IOregService) -> Bool { var modelIdentifier: String = "" @@ -267,14 +278,6 @@ class Arm64DDC: NSObject { if let modelData = IORegistryEntryCreateCFProperty(platformExpertDevice, "model" as CFString, kCFAllocatorDefault, 0).takeRetainedValue() as? Data, let modelIdentifierCString = String(data: modelData, encoding: .utf8)?.cString(using: .utf8) { modelIdentifier = String(cString: modelIdentifierCString) } - // This is a well known dummy plug (not a real display) but it breaks DDC communication on M1 - if ioregService.manufacturerID == "AOC", ioregService.productName == "28E850" { - 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 if ioregService.transportDownstream == "HDMI", ioregService.serviceLocation == 1, modelIdentifier == "Macmini9,1" { return true diff --git a/MonitorControl/Support/DisplayManager.swift b/MonitorControl/Support/DisplayManager.swift index 062e248..f6e07a3 100644 --- a/MonitorControl/Support/DisplayManager.swift +++ b/MonitorControl/Support/DisplayManager.swift @@ -313,7 +313,11 @@ class DisplayManager { os_log("Display service match successful for display %{public}@", type: .info, String(serviceMatch.displayID)) if serviceMatch.isDiscouraged { os_log("Display %{public}@ is flagged as discouraged by Arm64DDC.", type: .info, String(serviceMatch.displayID)) - otherDisplay.isDiscouraged = serviceMatch.isDiscouraged + otherDisplay.isDiscouraged = true + } else if serviceMatch.isDummy { + os_log("Display %{public}@ is flagged as dummy by Arm64DDC.", type: .info, String(serviceMatch.displayID)) + otherDisplay.isDiscouraged = true + otherDisplay.isDummy = true } else { otherDisplay.arm64ddc = DEBUG_SW ? false : true // MARK: (point of interest when testing) } @@ -396,7 +400,7 @@ class DisplayManager { static func isDummy(displayID: CGDirectDisplayID) -> Bool { let rawName = DisplayManager.getDisplayRawNameByID(displayID: displayID) var isDummy: Bool = false - if rawName == "28E850" || rawName.lowercased().contains("dummy") { + if rawName.lowercased().contains("dummy") { os_log("NOTE: Display is a dummy!", type: .info) isDummy = true } diff --git a/MonitorControlHelper/Info.plist b/MonitorControlHelper/Info.plist index 7298759..0d25c8c 100644 --- a/MonitorControlHelper/Info.plist +++ b/MonitorControlHelper/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion - 6956 + 6957 LSApplicationCategoryType public.app-category.utilities LSBackgroundOnly diff --git a/README.md b/README.md index f7d3e01..a92b5cd 100644 --- a/README.md +++ b/README.md @@ -99,11 +99,7 @@ _* With some limitations - full functionality available on macOS 11 Big Sur or n - LCD and LED Televisions usually do not implement DDC, these are supported using software alternatives to dim the image (some higher-end sets are able to translate this into hardware backlight dimming). - OLED or mini/micro-LED displays and televisions are fully supported using gamma table manipulation (this is a no-compromise solution for this class of displays). - DisplayLink, Airplay and Sidecar are supported using shade (dark overlay) control. - -Dummy compatibility: - - The app is compatible with [BetterDummy](https://github.com/waydabber/BetterDummy) mirrored sets. -- The app is compatible with mirrored sets that include a dummy dongle identifying as `28E850` Notable exceptions for hardware control compatibility: