Reputation: 686
I’m trying to retrieve a list of names of the displays connected to my Mac. Using NSScreen
, I can get the list as follows:
func getDisplayNames() -> [String] {
var names = [String]()
guard !NSScreen.screens.isEmpty else {
printLog("S3", "No displays are connected.")
return names
}
NSScreen.screens.forEach {
names.append($0.localizedName)
}
printLog("S3", "Connected to the following displays: \(names)")
return names
}
However, if the program is still running and I disconnect the external display, the list returned in the next iteration of the loop remains the same, as if the display were still connected. For example, if the list is ["LG IPS FULLHD", "Built-in Retina Display"]
when the external display is connected, it should become ["Built-in Retina Display"]
when the external display is disconnected. Instead, it stays as ["LG IPS FULLHD", "Built-in Retina Display"]
.
I found that using CGGetOnlineDisplayList
works correctly:
import CoreGraphics
func getOnlineDisplays() {
let maxDisplays: UInt32 = 10
var onlineDisplays = [CGDirectDisplayID](repeating: 0, count: Int(maxDisplays))
var displayCount: UInt32 = 0
let error = CGGetOnlineDisplayList(maxDisplays, &onlineDisplays, &displayCount)
if error == .success {
print("Number of online displays: \(displayCount)")
for i in 0..<displayCount {
print("Display ID \(i): \(onlineDisplays[Int(i)])")
}
} else {
print("Error retrieving online displays: \(error)")
}
}
// Call the function to get online displays
getOnlineDisplays()
As described enter link description here, this returns the IDs correctly (one ID when the display is not connected and two when it is). However, I haven’t found a way to convert the display ID into the corresponding display name.
Question: Is there a way to map the CGDirectDisplayID values returned by CGGetOnlineDisplayList to their respective localized names? Any guidance on this would be appreciated!
Upvotes: 0
Views: 118
Reputation: 686
I have followed the suggestion of @Willeke by trying with:
import Cocoa
import Combine
_ = NSApplication.shared
while true {
RunLoop.main.acceptInput(forMode: .default, before: .distantPast)
let displayList: [String] = getDisplayNames()
print(displayList)
}
as explained in NSScreen not updating monitor count when new monitors are plugged in and work as expected
Upvotes: 0