From a93994f0f2b351354aaaf0aa419eb6fb0af13b20 Mon Sep 17 00:00:00 2001 From: Serhiy Mytrovtsiy Date: Sat, 19 Dec 2020 19:38:39 +0100 Subject: [PATCH] feat: added the option to show a GPU type when Mini widget selected (#111, #232); fix: duplicating GPU the toggle the module --- Modules/GPU/main.swift | 30 ++++++++-- Modules/GPU/reader.swift | 48 ++++++++-------- Modules/GPU/settings.swift | 56 +++++++++++++++---- .../de.lproj/Localizable.strings | 1 + .../en.lproj/Localizable.strings | 1 + .../es.lproj/Localizable.strings | 1 + .../fr.lproj/Localizable.strings | 1 + .../it.lproj/Localizable.strings | 1 + .../ko.lproj/Localizable.strings | 1 + .../nb.lproj/Localizable.strings | 1 + .../pl.lproj/Localizable.strings | 1 + .../pt-BR.lproj/Localizable.strings | 1 + .../ru.lproj/Localizable.strings | 1 + .../tr.lproj/Localizable.strings | 1 + .../uk.lproj/Localizable.strings | 1 + .../vi.lproj/Localizable.strings | 1 + .../zh-Hans.lproj/Localizable.strings | 1 + .../zh-Hant.lproj/Localizable.strings | 1 + 18 files changed, 109 insertions(+), 40 deletions(-) diff --git a/Modules/GPU/main.swift b/Modules/GPU/main.swift index e49f2552..33d3372e 100644 --- a/Modules/GPU/main.swift +++ b/Modules/GPU/main.swift @@ -13,9 +13,19 @@ import Cocoa import ModuleKit import StatsKit +public typealias GPU_type = String +public enum GPU_types: GPU_type { + case unknown = "" + + case integrated = "i" + case external = "e" + case discrete = "d" +} + public struct GPU_Info { public let model: String public let IOClass: String + public let type: GPU_type public var state: Bool = false public var utilization: Double = 0 @@ -29,10 +39,6 @@ public struct GPUs: value_t { return self.list.filter{ $0.state } } - internal func igpu() -> GPU_Info? { - return self.active().first{ $0.IOClass == "IntelAccelerator" } - } - public var widget_value: Double { get { return list.isEmpty ? 0 : list[0].utilization @@ -50,6 +56,12 @@ public class GPU: Module { private var selectedGPU: String = "" + private var showType: Bool { + get { + return self.store.pointee.bool(key: "\(self.config.name)_showType", defaultValue: false) + } + } + public init(_ store: UnsafePointer, _ smc: UnsafePointer) { self.store = store self.smc = smc @@ -80,6 +92,9 @@ public class GPU: Module { self.settingsView.setInterval = { [unowned self] value in self.infoReader?.setInterval(value) } + self.settingsView.callback = { + self.infoReader?.read() + } if let reader = self.infoReader { self.addReader(reader) @@ -97,11 +112,14 @@ public class GPU: Module { self.settingsView.setList(value) let activeGPUs = value.active() - let activeGPU = activeGPUs.first{ $0.state } ?? activeGPUs[0] - let selectedGPU: GPU_Info = activeGPUs.first{ $0.model == self.selectedGPU } ?? value.igpu() ?? activeGPU + guard let activeGPU = activeGPUs.first(where: { $0.state }) ?? activeGPUs.first else { + return + } + let selectedGPU: GPU_Info = activeGPUs.first{ $0.model == self.selectedGPU } ?? activeGPU if let widget = self.widget as? Mini { widget.setValue(selectedGPU.utilization) + widget.setTitle(self.showType ? "\(selectedGPU.type)GPU" : nil) } if let widget = self.widget as? LineChart { widget.setValue(selectedGPU.utilization) diff --git a/Modules/GPU/reader.swift b/Modules/GPU/reader.swift index 0fbe7ce8..4ab5284c 100644 --- a/Modules/GPU/reader.swift +++ b/Modules/GPU/reader.swift @@ -53,10 +53,7 @@ internal class InfoReader: Reader { guard let accelerators = fetchIOService(kIOAcceleratorClassName) else { return } - - for (i, _) in self.devices.enumerated() { - self.devices[i].used = false - } + var devices = self.devices accelerators.forEach { (accelerator: NSDictionary) in guard let IOClass = accelerator.object(forKey: "IOClass") as? String else { @@ -72,33 +69,38 @@ internal class InfoReader: Reader { var model: String = "" let accMatch = (accelerator["IOPCIMatch"] as? String ?? accelerator["IOPCIPrimaryMatch"] as? String ?? "").lowercased() - for (i, device) in self.devices.enumerated() { - let matched = accMatch.range(of: device.pci) - if matched != nil && !device.used { + for (i, device) in devices.enumerated() { + if accMatch.range(of: device.pci) != nil && !device.used { model = device.model - self.devices[i].used = true - } else if device.used { - print("Device `\(device.model)` with pci `\(device.pci)` is already used", to: &Log.log) - } else { - print("`\(device.pci)` and `\(accMatch)` not match", to: &Log.log) + devices[i].used = true + break } } + let ioClass = IOClass.lowercased() + var predictModel = "" + var type: GPU_types = .unknown + + if ioClass == "nvAccelerator" || ioClass.contains("nvidia") { + predictModel = "Nvidia Graphics" + type = .discrete + } else if ioClass.contains("amd") { + predictModel = "AMD Graphics" + type = .discrete + } else if ioClass.contains("intel") { + predictModel = "Intel Graphics" + type = .integrated + } else { + predictModel = "Unknown" + type = .unknown + } + if model == "" { - let ioClass = IOClass.lowercased() - if ioClass == "nvAccelerator" || ioClass.contains("nvidia") { - model = "Nvidia Graphics" - } else if ioClass.contains("amd") { - model = "AMD Graphics" - } else if ioClass.contains("intel") { - model = "Intel Graphics" - } else { - model = "Unknown" - } + model = predictModel } if self.gpus.list.first(where: { $0.model == model }) == nil { - self.gpus.list.append(GPU_Info(model: model, IOClass: IOClass)) + self.gpus.list.append(GPU_Info(model: model, IOClass: IOClass, type: type.rawValue)) } guard let idx = self.gpus.list.firstIndex(where: { $0.model == model }) else { return diff --git a/Modules/GPU/settings.swift b/Modules/GPU/settings.swift index c7222334..c673c523 100644 --- a/Modules/GPU/settings.swift +++ b/Modules/GPU/settings.swift @@ -16,6 +16,7 @@ import ModuleKit internal class Settings: NSView, Settings_v { private var updateIntervalValue: Int = 1 private var selectedGPU: String + private var showTypeValue: Bool = false private let title: String private let store: UnsafePointer @@ -32,6 +33,7 @@ internal class Settings: NSView, Settings_v { self.store = store self.selectedGPU = store.pointee.string(key: "\(self.title)_gpu", defaultValue: "") self.updateIntervalValue = store.pointee.int(key: "\(self.title)_updateInterval", defaultValue: self.updateIntervalValue) + self.showTypeValue = store.pointee.bool(key: "\(self.title)_showType", defaultValue: self.showTypeValue) super.init(frame: CGRect( x: 0, @@ -52,28 +54,47 @@ internal class Settings: NSView, Settings_v { self.subviews.forEach{ $0.removeFromSuperview() } let rowHeight: CGFloat = 30 - let num: CGFloat = 1 + let num: CGFloat = widget == .mini ? 3 : 2 self.addSubview(SelectTitleRow( - frame: NSRect(x: Constants.Settings.margin, y: Constants.Settings.margin + (rowHeight + Constants.Settings.margin) * num, width: self.frame.width - (Constants.Settings.margin*2), height: rowHeight), + frame: NSRect( + x: Constants.Settings.margin, + y: Constants.Settings.margin + (rowHeight + Constants.Settings.margin) * (num-1), + width: self.frame.width - (Constants.Settings.margin*2), + height: rowHeight + ), title: LocalizedString("Update interval"), action: #selector(changeUpdateInterval), items: ReaderUpdateIntervals.map{ "\($0) sec" }, selected: "\(self.updateIntervalValue) sec" )) - self.addGPUSelector() + if widget == .mini { + self.addSubview(ToggleTitleRow( + frame: NSRect( + x: Constants.Settings.margin, + y: Constants.Settings.margin + (rowHeight + Constants.Settings.margin) * 1, + width: self.frame.width - (Constants.Settings.margin*2), + height: rowHeight + ), + title: LocalizedString("Show GPU type"), + action: #selector(toggleShowType), + state: self.showTypeValue + )) + } - self.setFrameSize(NSSize(width: self.frame.width, height: (rowHeight*(num+1)) + (Constants.Settings.margin*(2+num)))) + self.addGPUSelector(frame: NSRect( + x: Constants.Settings.margin, + y: Constants.Settings.margin + (rowHeight + Constants.Settings.margin) * 0, + width: self.frame.width - (Constants.Settings.margin*2), + height: rowHeight + )) + + self.setFrameSize(NSSize(width: self.frame.width, height: (rowHeight*num) + (Constants.Settings.margin*(num+1)))) } - private func addGPUSelector() { - let view: NSView = NSView(frame: NSRect( - x: Constants.Settings.margin, - y: Constants.Settings.margin, - width: self.frame.width - Constants.Settings.margin*2, - height: 30 - )) + private func addGPUSelector(frame: NSRect) { + let view: NSView = NSView(frame: frame) let rowTitle: NSTextField = LabelField(frame: NSRect( x: 0, @@ -145,4 +166,17 @@ internal class Settings: NSView, Settings_v { self.store.pointee.set(key: "\(self.title)_gpu", value: key) self.selectedGPUHandler(key) } + + @objc func toggleShowType(_ sender: NSControl) { + var state: NSControl.StateValue? = nil + if #available(OSX 10.15, *) { + state = sender is NSSwitch ? (sender as! NSSwitch).state: nil + } else { + state = sender is NSButton ? (sender as! NSButton).state: nil + } + + self.showTypeValue = state! == .on ? true : false + self.store.pointee.set(key: "\(self.title)_showType", value: self.showTypeValue) + self.callback() + } } diff --git a/Stats/Supporting Files/de.lproj/Localizable.strings b/Stats/Supporting Files/de.lproj/Localizable.strings index f9d4cacb..f1cf7cdd 100644 --- a/Stats/Supporting Files/de.lproj/Localizable.strings +++ b/Stats/Supporting Files/de.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "GPU auswählen"; +"Show GPU type" = "GPU Typ anzeigen"; "GPU temperature" = "GPU Temperatur"; "GPU utilization" = "GPU Nutzung"; diff --git a/Stats/Supporting Files/en.lproj/Localizable.strings b/Stats/Supporting Files/en.lproj/Localizable.strings index 02a97595..8b0ead31 100644 --- a/Stats/Supporting Files/en.lproj/Localizable.strings +++ b/Stats/Supporting Files/en.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "GPU to show"; +"Show GPU type" = "Show GPU type"; "GPU temperature" = "GPU temperature"; "GPU utilization" = "GPU utilization"; diff --git a/Stats/Supporting Files/es.lproj/Localizable.strings b/Stats/Supporting Files/es.lproj/Localizable.strings index 5eef395f..4fbfa44f 100644 --- a/Stats/Supporting Files/es.lproj/Localizable.strings +++ b/Stats/Supporting Files/es.lproj/Localizable.strings @@ -98,6 +98,7 @@ // GPU "GPU to show" = "GPU a mostrar"; +"Show GPU type" = "Mostrar tipo de GPU"; "GPU temperature" = "Temperatura de la GPU"; "GPU utilization" = "Utilización de la GPU"; diff --git a/Stats/Supporting Files/fr.lproj/Localizable.strings b/Stats/Supporting Files/fr.lproj/Localizable.strings index a0d6e9e9..e6447a98 100644 --- a/Stats/Supporting Files/fr.lproj/Localizable.strings +++ b/Stats/Supporting Files/fr.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "GPU à afficher"; +"Show GPU type" = "Afficher le type de GPU"; "GPU temperature" = "Température du GPU"; "GPU utilization" = "Utilisation du GPU"; diff --git a/Stats/Supporting Files/it.lproj/Localizable.strings b/Stats/Supporting Files/it.lproj/Localizable.strings index 4ec735ff..56ed1269 100644 --- a/Stats/Supporting Files/it.lproj/Localizable.strings +++ b/Stats/Supporting Files/it.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "GPU da mostrare"; +"Show GPU type" = "Mostra il tipo di GPU"; "GPU temperature" = "Temperatura GPU"; "GPU utilization" = "Utilizzo GPU"; diff --git a/Stats/Supporting Files/ko.lproj/Localizable.strings b/Stats/Supporting Files/ko.lproj/Localizable.strings index 8fa201e1..6423c53d 100644 --- a/Stats/Supporting Files/ko.lproj/Localizable.strings +++ b/Stats/Supporting Files/ko.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "표시할 GPU"; +"Show GPU type" = "GPU 유형 표시"; "GPU temperature" = "GPU 온도"; "GPU utilization" = "GPU 활용"; diff --git a/Stats/Supporting Files/nb.lproj/Localizable.strings b/Stats/Supporting Files/nb.lproj/Localizable.strings index 6590a5f5..4ddd9633 100644 --- a/Stats/Supporting Files/nb.lproj/Localizable.strings +++ b/Stats/Supporting Files/nb.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "GPU å vise"; +"Show GPU type" = "Vis GPU-typen"; "GPU temperature" = "GPU-temperatur"; "GPU utilization" = "GPU-bruk"; diff --git a/Stats/Supporting Files/pl.lproj/Localizable.strings b/Stats/Supporting Files/pl.lproj/Localizable.strings index 6698c0f8..75f26719 100644 --- a/Stats/Supporting Files/pl.lproj/Localizable.strings +++ b/Stats/Supporting Files/pl.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "GPU do wyświetlania"; +"Show GPU type" = "Pokaż typ GPU"; "GPU temperature" = "Temperatura GPU"; "GPU utilization" = "Obciążenie GPU"; diff --git a/Stats/Supporting Files/pt-BR.lproj/Localizable.strings b/Stats/Supporting Files/pt-BR.lproj/Localizable.strings index fb027b57..aeec29fb 100644 --- a/Stats/Supporting Files/pt-BR.lproj/Localizable.strings +++ b/Stats/Supporting Files/pt-BR.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "GPU para mostrar"; +"Show GPU type" = "Mostrar tipo de GPU"; "GPU temperature" = "Temperatura da GPU"; "GPU utilization" = "Utilização da GPU"; diff --git a/Stats/Supporting Files/ru.lproj/Localizable.strings b/Stats/Supporting Files/ru.lproj/Localizable.strings index e8f127d9..bdde7a87 100644 --- a/Stats/Supporting Files/ru.lproj/Localizable.strings +++ b/Stats/Supporting Files/ru.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "Активный графический процессор"; +"Show GPU type" = "Отображать тип графического процессора"; "GPU temperature" = "Температура графического процессора"; "GPU utilization" = "Использование графического процессора"; diff --git a/Stats/Supporting Files/tr.lproj/Localizable.strings b/Stats/Supporting Files/tr.lproj/Localizable.strings index 465e9961..086a9a11 100644 --- a/Stats/Supporting Files/tr.lproj/Localizable.strings +++ b/Stats/Supporting Files/tr.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "Gösterilecek GPU"; +"Show GPU type" = "GPU türünü göster"; "GPU temperature" = "GPU sıcaklığı"; "GPU utilization" = "GPU kullanımı"; diff --git a/Stats/Supporting Files/uk.lproj/Localizable.strings b/Stats/Supporting Files/uk.lproj/Localizable.strings index ec858dbf..70dac0e1 100644 --- a/Stats/Supporting Files/uk.lproj/Localizable.strings +++ b/Stats/Supporting Files/uk.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "Активний графічний процесор"; +"Show GPU type" = "Показувати тип графічного процесора"; "GPU temperature" = "Температура графічного процесора"; "GPU utilization" = "Навантаженість графічного процесора"; diff --git a/Stats/Supporting Files/vi.lproj/Localizable.strings b/Stats/Supporting Files/vi.lproj/Localizable.strings index 23e6de51..eb121581 100644 --- a/Stats/Supporting Files/vi.lproj/Localizable.strings +++ b/Stats/Supporting Files/vi.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "GPU để hiển thị"; +"Show GPU type" = "Hiển thị loại GPU"; "GPU temperature" = "Nhiệt độ GPU"; "GPU utilization" = "Sử dụng GPU"; diff --git a/Stats/Supporting Files/zh-Hans.lproj/Localizable.strings b/Stats/Supporting Files/zh-Hans.lproj/Localizable.strings index 1c89f373..7c76283d 100644 --- a/Stats/Supporting Files/zh-Hans.lproj/Localizable.strings +++ b/Stats/Supporting Files/zh-Hans.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "显示的GPU"; +"Show GPU type" = "显示GPU类型"; "GPU temperature" = "GPU温度"; "GPU utilization" = "GPU利用率"; diff --git a/Stats/Supporting Files/zh-Hant.lproj/Localizable.strings b/Stats/Supporting Files/zh-Hant.lproj/Localizable.strings index ee879cc9..db4bc0f9 100644 --- a/Stats/Supporting Files/zh-Hant.lproj/Localizable.strings +++ b/Stats/Supporting Files/zh-Hant.lproj/Localizable.strings @@ -97,6 +97,7 @@ // GPU "GPU to show" = "顯示 GPU"; +"Show GPU type" = "顯示GPU類型"; "GPU temperature" = "GPU 溫度"; "GPU utilization" = "GPU 使用率";