feat: added display information to the Dashboard

This commit is contained in:
Serhiy Mytrovtsiy
2025-10-02 19:03:46 +02:00
parent a07c3cf323
commit f40b5dd12a
3 changed files with 110 additions and 5 deletions

View File

@@ -350,11 +350,12 @@ public extension NSView {
return button
}
func textView(_ value: String) -> NSTextField {
func textView(_ value: String, alignment: NSTextAlignment = .left) -> NSTextField {
let field: NSTextField = TextView()
field.font = NSFont.systemFont(ofSize: 13, weight: .regular)
field.stringValue = value
field.isSelectable = true
field.alignment = alignment
return field
}

View File

@@ -140,6 +140,20 @@ public struct disk_s: Codable {
public var size: Int64? = nil
}
public struct display_s: Codable {
public var id: String? = nil
public var name: String? = nil
public var resolution: CGSize? = nil
public var size: Double? = nil
public var refreshRate: Double? = nil
public var isBuiltIn: Bool? = nil
public var isMain: Bool? = nil
public var vendor: String? = nil
public var model: String? = nil
public var serialNumber: String? = nil
}
public struct info_s {
public var cpu: cpu_s? = nil
public var ram: ram_s? = nil
@@ -160,6 +174,7 @@ public struct device_s {
public var os: os_s? = nil
public var info: info_s = info_s()
public var platform: Platform? = nil
public var display: [display_s]? = nil
}
public class SystemKit {
@@ -205,6 +220,7 @@ public class SystemKit {
self.device.info.gpu = self.getGPUInfo()
self.device.info.disk = self.getDiskInfo()
self.device.platform = self.getPlatform()
self.device.display = self.getDisplayInfo()
}
public func getModelID() -> String? {
@@ -702,6 +718,61 @@ public class SystemKit {
}
return nil
}
private func getDisplayInfo() -> [display_s]? {
var displays: [display_s] = []
for screen in NSScreen.screens {
guard let displayID = screen.deviceDescription[NSDeviceDescriptionKey(rawValue: "NSScreenNumber")] as? CGDirectDisplayID else {
continue
}
let mmSize = CGDisplayScreenSize(displayID)
let widthInches = mmSize.width / 25.4
let heightInches = mmSize.height / 25.4
let diagonal = sqrt(widthInches * widthInches + heightInches * heightInches)
var display = display_s(
id: String(displayID),
size: diagonal.rounded(),
isBuiltIn: CGDisplayIsBuiltin(displayID) != 0,
isMain: CGDisplayIsMain(displayID) != 0,
vendor: String(CGDisplayVendorNumber(displayID)),
model: String(CGDisplayModelNumber(displayID)),
serialNumber: String(CGDisplaySerialNumber(displayID))
)
if let mode = CGDisplayCopyDisplayMode(displayID) {
let pw = mode.pixelWidth
let ph = mode.pixelHeight
let width = pw > 0 ? pw : CGDisplayPixelsWide(displayID)
let height = ph > 0 ? ph : CGDisplayPixelsHigh(displayID)
display.resolution = CGSize(width: width, height: height)
let hz = mode.refreshRate
display.refreshRate = hz > 0 ? hz : nil
} else {
let width = CGDisplayPixelsWide(displayID)
let height = CGDisplayPixelsHigh(displayID)
if width > 0 && height > 0 {
display.resolution = CGSize(width: width, height: height)
}
}
display.name = screen.localizedName
if display.name == nil {
if display.isMain == true {
display.name = display.isBuiltIn == true ? "Built-in Display" : "External Display (Main)"
} else {
display.name = display.isBuiltIn == true ? "Built-in Display" : "External Display"
}
}
displays.append(display)
}
return displays.isEmpty ? nil : displays
}
}
let deviceDict: [String: model_s] = [

View File

@@ -158,6 +158,38 @@ class Dashboard: NSStackView {
return value
}
private var displaysValue: String {
guard let displays = SystemKit.shared.device.display else {
return localizedString("Unknown")
}
var value = ""
for i in 0..<displays.count {
var row = displays[i].name != nil ? displays[i].name! : localizedString("Unknown")
if let size = displays[i].size {
let displaySize = String(format: "%.1f", size).replacingOccurrences(of: ".0", with: "")
row += " (\(displaySize)\")"
}
if displays[i].resolution != nil || displays[i].refreshRate != nil {
var details = ""
if let res = displays[i].resolution {
details = "\(Int(res.width))x\(Int(res.height))"
}
if let rr = displays[i].refreshRate {
if !details.isEmpty {
details += ", "
}
details += "\(String(format: "%.0f", rr))Hz"
}
if !details.isEmpty {
row += "\n\(details)"
}
}
value += "\(row)\(i == displays.count-1 ? "" : "\n")"
}
return value
}
private var uptimeValue: String {
let form = DateComponentsFormatter()
form.maximumUnitCount = 2
@@ -191,10 +223,11 @@ class Dashboard: NSStackView {
scrollView.stackView.addArrangedSubview(self.deviceView())
scrollView.stackView.addArrangedSubview(PreferencesSection([
PreferencesRow(localizedString("Processor"), "", component: textView(self.processorValue)),
PreferencesRow(localizedString("Memory"), component: textView(self.memoryValue)),
PreferencesRow(localizedString("Graphics"), component: textView(self.graphicsValue)),
PreferencesRow(localizedString("Disks"), component: textView(self.disksValue))
PreferencesRow(localizedString("Processor"), "", component: textView(self.processorValue, alignment: .right)),
PreferencesRow(localizedString("Memory"), component: textView(self.memoryValue, alignment: .right)),
PreferencesRow(localizedString("Graphics"), component: textView(self.graphicsValue, alignment: .right)),
PreferencesRow(localizedString("Disks"), component: textView(self.disksValue, alignment: .right)),
PreferencesRow(localizedString("Displays"), "", component: textView(self.displaysValue, alignment: .right))
]))
scrollView.stackView.addArrangedSubview(PreferencesSection([