diff --git a/Kit/helpers.swift b/Kit/helpers.swift index 1b8db070897..c97d2a1cc6b 100644 --- a/Kit/helpers.swift +++ b/Kit/helpers.swift @@ -662,6 +662,23 @@ internal func getIOName(_ entry: io_registry_entry_t) -> String? { return String(cString: UnsafeRawPointer(pointer).assumingMemoryBound(to: CChar.self)) } +internal func convertCFDataToArr(_ data: CFData) -> [Int32] { + let length = CFDataGetLength(data) + var bytes = [UInt8](repeating: 0, count: length) + CFDataGetBytes(data, CFRange(location: 0, length: length), &bytes) + + var arr: [Int32] = [] + var chunks = stride(from: 0, to: bytes.count, by: 8).map { Array(bytes[$0.. ([Int32], [Int32], [Int32])? { + var iterator = io_iterator_t() + let result = IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("AppleARMIODevice"), &iterator) + if result != kIOReturnSuccess { + print("Error find AppleARMIODevice: " + (String(cString: mach_error_string(result), encoding: String.Encoding.ascii) ?? "unknown error")) + return nil + } + + var eFreq: [Int32] = [] + var pFreq: [Int32] = [] + var gpuFreq: [Int32] = [] + + while case let child = IOIteratorNext(iterator), child != 0 { + defer { IOObjectRelease(child) } + guard let name = getIOName(child), name == "pmgr", let props = getIOProperties(child) else { continue } + + if let data = props.value(forKey: "voltage-states1-sram") { + eFreq = convertCFDataToArr(data as! CFData) + } + if let data = props.value(forKey: "voltage-states5-sram") { + pFreq = convertCFDataToArr(data as! CFData) + } + if let data = props.value(forKey: "voltage-states9-sram") { + gpuFreq = convertCFDataToArr(data as! CFData) + } + } + + return (eFreq, pFreq, gpuFreq) + } + public func getRamInfo() -> ram_s? { guard let res = process(path: "/usr/sbin/system_profiler", arguments: ["SPMemoryDataType", "-json"]) else { return nil diff --git a/Modules/CPU/bridge.h b/Modules/CPU/bridge.h new file mode 100644 index 00000000000..77a8622fea3 --- /dev/null +++ b/Modules/CPU/bridge.h @@ -0,0 +1,32 @@ +// +// bridge.h +// Stats +// +// Created by Serhiy Mytrovtsiy on 17/12/2024 +// Using Swift 6.0 +// Running on macOS 15.1 +// +// Copyright © 2024 Serhiy Mytrovtsiy. All rights reserved. +// + +#ifndef bridge_h +#define bridge_h + +#include + +typedef struct IOReportSubscriptionRef* IOReportSubscriptionRef; + +CFDictionaryRef IOReportCopyChannelsInGroup(CFStringRef a, CFStringRef b, uint64_t c, uint64_t d, uint64_t e); +void IOReportMergeChannels(CFDictionaryRef a, CFDictionaryRef b, CFTypeRef null); +IOReportSubscriptionRef IOReportCreateSubscription(void* a, CFMutableDictionaryRef b, CFMutableDictionaryRef* c, uint64_t d, CFTypeRef e); +CFDictionaryRef IOReportCreateSamples(IOReportSubscriptionRef a, CFMutableDictionaryRef b, CFTypeRef c); +CFDictionaryRef IOReportCreateSamplesDelta(CFDictionaryRef a, CFDictionaryRef b, CFTypeRef c); +CFStringRef IOReportChannelGetGroup(CFDictionaryRef a); +CFStringRef IOReportChannelGetSubGroup(CFDictionaryRef a); +CFStringRef IOReportChannelGetChannelName(CFDictionaryRef a); +CFStringRef IOReportChannelGetUnitLabel(CFDictionaryRef a); +int32_t IOReportStateGetCount(CFDictionaryRef a); +CFStringRef IOReportStateGetNameForIndex(CFDictionaryRef a, int32_t b); +int64_t IOReportStateGetResidency(CFDictionaryRef a, int32_t b); + +#endif /* bridge_h */ diff --git a/Modules/CPU/main.swift b/Modules/CPU/main.swift index 1c8313ac9f7..13afb2e9cf8 100644 --- a/Modules/CPU/main.swift +++ b/Modules/CPU/main.swift @@ -75,7 +75,7 @@ public class CPU: Module { return color.additional as! NSColor } private var pCoreColor: NSColor { - let color = SColor.secondBlue + let color = SColor.indigo let key = Store.shared.string(key: "\(self.config.name)_pCoresColor", defaultValue: color.key) if let c = SColor.fromString(key).additional as? NSColor { return c @@ -115,7 +115,8 @@ public class CPU: Module { self.limitReader = LimitReader(.CPU, popup: true) { [weak self] value in self?.popupView.limitCallback(value) } - self.frequencyReader = FrequencyReader(.CPU, popup: true) { [weak self] value in + #else + self.frequencyReader = FrequencyReader(.CPU, popup: false) { [weak self] value in self?.popupView.frequencyCallback(value) } #endif @@ -135,12 +136,6 @@ public class CPU: Module { self.settingsView.setTopInterval = { [weak self] value in self?.processReader?.setInterval(value) } - self.settingsView.IPGCallback = { [weak self] value in - if value { - self?.frequencyReader?.setup() - } - self?.popupView.toggleFrequency(state: value) - } self.setReaders([ self.loadReader, diff --git a/Modules/CPU/popup.swift b/Modules/CPU/popup.swift index 648986f1d7a..479c3b63705 100644 --- a/Modules/CPU/popup.swift +++ b/Modules/CPU/popup.swift @@ -32,6 +32,18 @@ internal class Popup: PopupWrapper { } } private let averageHeight: CGFloat = (22*3) + Constants.Popup.separatorHeight + private var frequencyHeight: CGFloat { + get { + var count: CGFloat = 1 + if SystemKit.shared.device.info.cpu?.eCores != nil { + count += 1 + } + if SystemKit.shared.device.info.cpu?.pCores != nil { + count += 1 + } + return (22*count) + Constants.Popup.separatorHeight + } + } private let processHeight: CGFloat = 22 private var systemField: NSTextField? = nil @@ -45,6 +57,11 @@ internal class Popup: PopupWrapper { private var average1Field: NSTextField? = nil private var average5Field: NSTextField? = nil private var average15Field: NSTextField? = nil + private var coresFreqField: NSTextField? = nil + private var eCoresFreqField: NSTextField? = nil + private var pCoresFreqField: NSTextField? = nil + private var eCoresFreqColorView: NSView? = nil + private var pCoresFreqColorView: NSView? = nil private var systemColorView: NSView? = nil private var userColorView: NSView? = nil @@ -83,7 +100,7 @@ internal class Popup: PopupWrapper { private var chartColor: NSColor { self.chartColorState.additional as? NSColor ?? NSColor.systemBlue } private var eCoresColorState: SColor = .teal private var eCoresColor: NSColor { self.eCoresColorState.additional as? NSColor ?? NSColor.systemTeal } - private var pCoresColorState: SColor = .secondBlue + private var pCoresColorState: SColor = .indigo private var pCoresColor: NSColor { self.pCoresColorState.additional as? NSColor ?? NSColor.systemBlue } private var numberOfProcesses: Int { @@ -115,7 +132,7 @@ internal class Popup: PopupWrapper { width: Constants.Popup.width, height: self.dashboardHeight + self.chartHeight + self.averageHeight )) - self.setFrameSize(NSSize(width: self.frame.width, height: self.frame.height + self.detailsHeight + self.processesHeight)) + self.setFrameSize(NSSize(width: self.frame.width, height: self.frame.height + self.detailsHeight + self.frequencyHeight + self.processesHeight)) self.systemColorState = SColor.fromString(Store.shared.string(key: "\(self.title)_systemColor", defaultValue: self.systemColorState.key)) self.userColorState = SColor.fromString(Store.shared.string(key: "\(self.title)_userColor", defaultValue: self.userColorState.key)) @@ -135,12 +152,14 @@ internal class Popup: PopupWrapper { gridView.addRow(with: [self.initChart()]) gridView.addRow(with: [self.initDetails()]) gridView.addRow(with: [self.initAverage()]) + gridView.addRow(with: [self.initFrequency()]) gridView.addRow(with: [self.initProcesses()]) gridView.row(at: 0).height = self.dashboardHeight gridView.row(at: 1).height = self.chartHeight gridView.row(at: 2).height = self.detailsHeight gridView.row(at: 3).height = self.averageHeight + gridView.row(at: 4).height = self.frequencyHeight self.addSubview(gridView) self.grid = gridView @@ -189,7 +208,7 @@ internal class Popup: PopupWrapper { let usage = NSView(frame: NSRect(x: usageX, y: (view.frame.height - usageSize)/2, width: usageSize, height: usageSize)) let temperature = NSView(frame: NSRect(x: (usageX - 50)/2, y: (view.frame.height - 50)/2 - 3, width: 50, height: 50)) - let frequency = NSView(frame: NSRect(x: (usageX+usageSize) + (usageX - 50)/2, y: (view.frame.height - 50)/2 - 3, width: 50, height: 50)) + let frequency = NSView(frame: NSRect(x: (usageX+usageSize) + (usageX - 50)/2, y: 0, width: 50, height: self.dashboardHeight)) self.circle = PieChartView(frame: NSRect(x: 0, y: 0, width: usage.frame.width, height: usage.frame.height), segments: [], drawValue: true) self.circle!.toolTip = localizedString("CPU usage") @@ -315,6 +334,30 @@ internal class Popup: PopupWrapper { return view } + private func initFrequency() -> NSView { + let view: NSView = NSView(frame: NSRect(x: 0, y: 0, width: self.frame.width, height: self.frequencyHeight)) + let separator = separatorView(localizedString("Frequency"), origin: NSPoint(x: 0, y: self.frequencyHeight-Constants.Popup.separatorHeight), width: self.frame.width) + let container: NSStackView = NSStackView(frame: NSRect(x: 0, y: 0, width: view.frame.width, height: separator.frame.origin.y)) + container.orientation = .vertical + container.spacing = 0 + + self.coresFreqField = popupRow(container, title: "\(localizedString("All cores")):", value: "").1 + + if isARM { + if SystemKit.shared.device.info.cpu?.eCores != nil { + (self.eCoresFreqColorView, _, self.eCoresFreqField) = popupWithColorRow(container, color: self.eCoresColor, title: "\(localizedString("Efficiency cores")):", value: "") + } + if SystemKit.shared.device.info.cpu?.pCores != nil { + (self.pCoresFreqColorView, _, self.pCoresFreqField) = popupWithColorRow(container, color: self.pCoresColor, title: "\(localizedString("Performance cores")):", value: "") + } + } + + view.addSubview(separator) + view.addSubview(container) + + return view + } + private func initProcesses() -> NSView { if self.numberOfProcesses == 0 { return NSView() } @@ -388,7 +431,7 @@ internal class Popup: PopupWrapper { }) } - public func frequencyCallback(_ value: Double?) { + public func frequencyCallback(_ value: [Double]?) { guard let value else { return } DispatchQueue.main.async(execute: { @@ -397,13 +440,33 @@ internal class Popup: PopupWrapper { } if (self.window?.isVisible ?? false) || !self.initializedFrequency { - if value > self.maxFreq { - self.maxFreq = value - } - - if let freqCircle = self.frequencyCircle { - freqCircle.setValue((100*value)/self.maxFreq) - freqCircle.setText("\((value/1000).rounded(toPlaces: 2))") + if value.count == 1 { + let freq = value.first ?? 0 + if freq > self.maxFreq { + self.maxFreq = freq + } + self.coresFreqField?.stringValue = "\(Int(freq)) MHz" + if let circle = self.frequencyCircle { + circle.setValue((100*freq)/self.maxFreq) + circle.setText("\((freq/1000).rounded(toPlaces: 2))") + } + } else if value.count == 2 { + let e = value.first ?? 0 + let p = value.last ?? 0 + self.eCoresFreqField?.stringValue = "\(Int(e)) MHz" + self.pCoresFreqField?.stringValue = "\(Int(p)) MHz" + + if let eCoreCount = SystemKit.shared.device.info.cpu?.eCores, let pCoreCount = SystemKit.shared.device.info.cpu?.pCores { + let freq = ((e * Double(eCoreCount)) + (p * Double(pCoreCount))) / Double(eCoreCount + pCoreCount) + if freq > self.maxFreq { + self.maxFreq = freq + } + self.coresFreqField?.stringValue = "\(Int(freq)) MHz" + if let circle = self.frequencyCircle { + circle.setValue((100*freq)/self.maxFreq) + circle.setText("\((freq/1000).rounded(toPlaces: 2))") + } + } } self.initializedFrequency = true @@ -461,15 +524,6 @@ internal class Popup: PopupWrapper { }) } - public func toggleFrequency(state: Bool) { - DispatchQueue.main.async(execute: { - if let view = self.frequencyCircle { - view.isHidden = !state - } - self.initializedFrequency = false - }) - } - // MARK: - Settings public override func settings() -> NSView? { @@ -578,7 +632,10 @@ internal class Popup: PopupWrapper { } self.eCoresColorState = newValue Store.shared.set(key: "\(self.title)_eCoresColor", value: key) - self.eCoresColorView?.layer?.backgroundColor = (newValue.additional as? NSColor)?.cgColor + if let color = (newValue.additional as? NSColor) { + self.eCoresColorView?.layer?.backgroundColor = color.cgColor + self.eCoresFreqColorView?.layer?.backgroundColor = color.cgColor + } } @objc private func togglePCoresColor(_ sender: NSMenuItem) { guard let key = sender.representedObject as? String, let newValue = SColor.allColors.first(where: { $0.key == key }) else { @@ -586,7 +643,10 @@ internal class Popup: PopupWrapper { } self.pCoresColorState = newValue Store.shared.set(key: "\(self.title)_pCoresColor", value: key) - self.pCoresColorView?.layer?.backgroundColor = (newValue.additional as? NSColor)?.cgColor + if let color = (newValue.additional as? NSColor) { + self.pCoresColorView?.layer?.backgroundColor = color.cgColor + self.pCoresFreqColorView?.layer?.backgroundColor = color.cgColor + } } @objc private func toggleLineChartHistory(_ sender: NSMenuItem) { guard let key = sender.representedObject as? String, let value = Int(key) else { return } diff --git a/Modules/CPU/portal.swift b/Modules/CPU/portal.swift index cc56e5b1f17..2674052541b 100644 --- a/Modules/CPU/portal.swift +++ b/Modules/CPU/portal.swift @@ -43,7 +43,7 @@ public class Portal: PortalWrapper { private var idleColor: NSColor { self.idleColorState.additional as? NSColor ?? NSColor.lightGray } private var eCoresColorState: SColor = .teal private var eCoresColor: NSColor { self.eCoresColorState.additional as? NSColor ?? NSColor.systemTeal } - private var pCoresColorState: SColor = .secondBlue + private var pCoresColorState: SColor = .indigo private var pCoresColor: NSColor { self.pCoresColorState.additional as? NSColor ?? NSColor.systemBlue } public override func load() { diff --git a/Modules/CPU/readers.swift b/Modules/CPU/readers.swift index 59130ddbeae..aba5b2dbe00 100644 --- a/Modules/CPU/readers.swift +++ b/Modules/CPU/readers.swift @@ -289,161 +289,173 @@ public class TemperatureReader: Reader { } } -public class FrequencyReader: Reader { - private typealias PGSample = UInt64 - private typealias UDouble = UnsafeMutablePointer +// inspired by https://github.com/shank03/StatsBar/blob/e175aa71c914ce882ce2e90163f3eb18262a8e25/StatsBar/Service/IOReport.swift +public class FrequencyReader: Reader<[Double]> { + private var eCoreFreqs: [Int32] = [] + private var pCoreFreqs: [Int32] = [] - private typealias PG_InitializePointerFunction = @convention(c) () -> Bool - private typealias PG_ShutdownPointerFunction = @convention(c) () -> Bool - private typealias PG_ReadSamplePointerFunction = @convention(c) (Int, UnsafeMutablePointer) -> Bool - private typealias PGSample_GetIAFrequencyPointerFunction = @convention(c) (PGSample, PGSample, UDouble, UDouble, UDouble) -> Bool - private typealias PGSample_ReleasePointerFunction = @convention(c) (PGSample) -> Bool + private var channels: CFMutableDictionary? = nil + private var subscription: IOReportSubscriptionRef? = nil + private var prev: (samples: CFDictionary, time: TimeInterval)? = nil - private var bundle: CFBundle? = nil + private let measurementCount: Int = 4 - private var pgIntialize: PG_InitializePointerFunction? = nil - private var pgShutdown: PG_ShutdownPointerFunction? = nil - private var pgReadSample: PG_ReadSamplePointerFunction? = nil - private var pgSampleGetIAFrequency: PGSample_GetIAFrequencyPointerFunction? = nil - private var pgSampleRelease: PGSample_ReleasePointerFunction? = nil - - private var sample: PGSample = 0 - private var reconnectAttempt: Int = 0 - - private var isEnabled: Bool { - get { - return Store.shared.bool(key: "CPU_IPG", defaultValue: false) - } + private struct IOSample { + let group: String + let subGroup: String + let channel: String + let unit: String + let delta: CFDictionary } public override func setup() { - guard self.isEnabled else { return } - - let path: CFString = "/Library/Frameworks/IntelPowerGadget.framework" as CFString - let bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path, CFURLPathStyle.cfurlposixPathStyle, true) - - self.bundle = CFBundleCreate(kCFAllocatorDefault, bundleURL) - if self.bundle == nil { - error("IntelPowerGadget framework not found", log: self.log) - return - } - - if !CFBundleLoadExecutable(self.bundle) { - error("failed to load IPG framework", log: self.log) - return - } - - guard let pgIntialize = CFBundleGetFunctionPointerForName(self.bundle, "PG_Initialize" as CFString) else { - error("failed to find PG_Initialize", log: self.log) - return - } - guard let pgShutdown = CFBundleGetFunctionPointerForName(self.bundle, "PG_Shutdown" as CFString) else { - error("failed to find PG_Shutdown", log: self.log) - return - } - guard let pgReadSample = CFBundleGetFunctionPointerForName(self.bundle, "PG_ReadSample" as CFString) else { - error("failed to find PG_ReadSample", log: self.log) - return - } - guard let pgSampleGetIAFrequency = CFBundleGetFunctionPointerForName(self.bundle, "PGSample_GetIAFrequency" as CFString) else { - error("failed to find PGSample_GetIAFrequency", log: self.log) - return - } - guard let pgSampleRelease = CFBundleGetFunctionPointerForName(self.bundle, "PGSample_Release" as CFString) else { - error("failed to find PGSample_Release", log: self.log) - return - } - - self.pgIntialize = unsafeBitCast(pgIntialize, to: PG_InitializePointerFunction.self) - self.pgShutdown = unsafeBitCast(pgShutdown, to: PG_ShutdownPointerFunction.self) - self.pgReadSample = unsafeBitCast(pgReadSample, to: PG_ReadSamplePointerFunction.self) - self.pgSampleGetIAFrequency = unsafeBitCast(pgSampleGetIAFrequency, to: PGSample_GetIAFrequencyPointerFunction.self) - self.pgSampleRelease = unsafeBitCast(pgSampleRelease, to: PGSample_ReleasePointerFunction.self) + self.eCoreFreqs = SystemKit.shared.device.info.cpu?.eCoreFrequencies ?? [] + self.pCoreFreqs = SystemKit.shared.device.info.cpu?.pCoreFrequencies ?? [] + self.channels = self.getChannels() + var dict: Unmanaged? + self.subscription = IOReportCreateSubscription(nil, self.channels, &dict, 0, nil) + } + + public override func read() { + guard !self.eCoreFreqs.isEmpty && !self.pCoreFreqs.isEmpty, self.channels != nil, self.subscription != nil else { return } + let minECoreFreq = Double(self.eCoreFreqs.min() ?? 0) + let minPCoreFreq = Double(self.pCoreFreqs.min() ?? 0) - if let initialize = self.pgIntialize { - if !initialize() { - error("IPG initialization failed", log: self.log) - return + Task { + var eCores: [Double] = [] + var pCores: [Double] = [] + + for (samples, _) in await self.getSamples() { + var eCore: [Double] = [] + var pCore: [Double] = [] + + for sample in samples { + guard sample.group == "CPU Stats" else { continue } + if sample.channel.starts(with: "ECPU") { + eCore.append(self.calculateFrequencies(dict: sample.delta, freqs: self.eCoreFreqs)) + } + if sample.channel.starts(with: "PCPU") { + pCore.append(self.calculateFrequencies(dict: sample.delta, freqs: self.pCoreFreqs)) + } + } + + let eCoresAvgFreq: Double = eCore.isEmpty ? 0 : (eCore.reduce(0.0, { $0 + $1 }) / Double(eCore.count)) + let pCoresAvgFreq: Double = pCore.isEmpty ? 0 : (pCore.reduce(0.0, { $0 + $1 }) / Double(pCore.count)) + eCores.append(max(eCoresAvgFreq, minECoreFreq)) + pCores.append(max(pCoresAvgFreq, minPCoreFreq)) } + + let eFreq: Double = eCores.reduce(0, { $0 + $1 }) / Double(self.measurementCount) + let pFreq: Double = pCores.reduce(0, { $0 + $1 }) / Double(self.measurementCount) + + self.callback([eFreq, pFreq]) } } - deinit { - if let bundle = self.bundle { - CFBundleUnloadExecutable(bundle) + private func calculateFrequencies(dict: CFDictionary, freqs: [Int32]) -> Double { + let items = self.getResidencies(dict: dict) + let offset = items.firstIndex { $0.0 != "IDLE" && $0.0 != "DOWN" && $0.0 != "OFF" }! + let usage = items.dropFirst(offset).reduce(0.0) { $0 + Double($1.f) } + let count = freqs.count + var avgFreq: Double = 0 + + for i in 0.. [(ns: String, f: Int64)] { + let count = IOReportStateGetCount(dict) + var res: [(String, Int64)] = [] - if let release = self.pgSampleRelease { - if self.sample != 0 { - _ = release(self.sample) - return - } + for i in 0..= 5 { - return + private func getChannels() -> CFMutableDictionary? { + let channelNames = [ + ("CPU Stats", "CPU Complex Performance States"), + ("CPU Stats", "CPU Core Performance States") + ] + + var channels: [CFDictionary] = [] + for (gname, sname) in channelNames { + let channel = IOReportCopyChannelsInGroup(gname as CFString?, sname as CFString?, 0, 0, 0) + guard let channel = channel?.takeRetainedValue() else { continue } + channels.append(channel) } - self.sample = 0 - self.terminate() - if let initialize = self.pgIntialize { - if !initialize() { - error("IPG initialization failed", log: self.log) - return - } + let chan = channels[0] + for i in 1.. [([IOSample], TimeInterval)] { + let duration = 500 + let step = UInt64(duration / self.measurementCount) + var prev = self.prev ?? self.getSample() ?? self.prev! + var samples = [([IOSample], TimeInterval)]() + + for _ in 0.. (samples: CFDictionary, time: TimeInterval)? { + guard let sample = IOReportCreateSamples(self.subscription, self.channels, nil)?.takeRetainedValue() else { + return nil } + return (sample, Date().timeIntervalSince1970) + } + + private func collectIOSamples(data: CFDictionary) -> [IOSample] { + let dict = data as! [String: Any] + let items = dict["IOReportChannels"] as! CFArray + let itemSize = CFArrayGetCount(items) - defer { - if !self.pgSampleRelease!(self.sample) { - error("release self.sample failed", log: self.log) - } - self.sample = local - } + var samples = [IOSample]() - if !self.pgSampleGetIAFrequency!(self.sample, local, &value, &min, &max) { - error("read frequency failed", log: self.log) - return + for index in 0.. Void) = {} public var callbackWhenUpdateNumberOfProcesses: (() -> Void) = {} - public var IPGCallback: ((_ state: Bool) -> Void) = {_ in } public var setInterval: ((_ value: Int) -> Void) = {_ in } public var setTopInterval: ((_ value: Int) -> Void) = {_ in } @@ -41,7 +39,6 @@ internal class Settings: NSStackView, Settings_v { self.hyperthreadState = Store.shared.bool(key: "\(self.title)_hyperhreading", defaultValue: self.hyperthreadState) self.usagePerCoreState = Store.shared.bool(key: "\(self.title)_usagePerCore", defaultValue: self.usagePerCoreState) self.splitValueState = Store.shared.bool(key: "\(self.title)_splitValue", defaultValue: self.splitValueState) - self.IPGState = Store.shared.bool(key: "\(self.title)_IPG", defaultValue: self.IPGState) self.updateIntervalValue = Store.shared.int(key: "\(self.title)_updateInterval", defaultValue: self.updateIntervalValue) self.updateTopIntervalValue = Store.shared.int(key: "\(self.title)_updateTopInterval", defaultValue: self.updateTopIntervalValue) self.numberOfProcesses = Store.shared.int(key: "\(self.title)_processes", defaultValue: self.numberOfProcesses) @@ -135,17 +132,6 @@ internal class Settings: NSStackView, Settings_v { self.addArrangedSubview(PreferencesSection(rows)) } - - #if arch(x86_64) - if hasIPG { - self.addArrangedSubview(PreferencesSection([ - PreferencesRow("\(localizedString("CPU frequency")) (IPG)", component: switchView( - action: #selector(self.toggleIPG), - state: self.IPGState - )) - ])) - } - #endif } @objc private func changeUpdateInterval(_ sender: NSMenuItem) { @@ -203,12 +189,6 @@ internal class Settings: NSStackView, Settings_v { self.callback() } - @objc func toggleIPG(_ sender: NSControl) { - self.IPGState = controlState(sender) - Store.shared.set(key: "\(self.title)_IPG", value: self.IPGState) - self.IPGCallback(self.IPGState) - } - @objc func toggleSplitValue(_ sender: NSControl) { self.splitValueState = controlState(sender) Store.shared.set(key: "\(self.title)_splitValue", value: self.splitValueState) diff --git a/Stats.xcodeproj/project.pbxproj b/Stats.xcodeproj/project.pbxproj index bd0f2b9a3a8..66ee6494303 100644 --- a/Stats.xcodeproj/project.pbxproj +++ b/Stats.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 5C0A9CAA2C46838A00EE6A89 /* GPU.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A90E18924EAD2BB00471E9A /* GPU.framework */; }; 5C0A9CAF2C46838F00EE6A89 /* RAM.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9A81C7562449A41400825D92 /* RAM.framework */; }; 5C0A9CB42C46839500EE6A89 /* Disk.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AF9EE0224648751005D2270 /* Disk.framework */; }; + 5C1E45562D11D66A00525864 /* libIOReport.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C1E45552D11D66200525864 /* libIOReport.tbd */; }; 5C21D80B296C7B81005BA16D /* CombinedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C21D80A296C7B81005BA16D /* CombinedView.swift */; }; 5C2229A329CCB3C400F00E69 /* Clock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5C22299D29CCB3C400F00E69 /* Clock.framework */; }; 5C2229A429CCB3C400F00E69 /* Clock.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 5C22299D29CCB3C400F00E69 /* Clock.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -495,6 +496,8 @@ 5C0A9CA12C467AA300EE6A89 /* widget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = widget.swift; sourceTree = ""; }; 5C0A9CA32C467F7A00EE6A89 /* widget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = widget.swift; sourceTree = ""; }; 5C0E550A2B5D545A00FFF1FB /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; }; + 5C1E45552D11D66200525864 /* libIOReport.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libIOReport.tbd; path = usr/lib/libIOReport.tbd; sourceTree = SDKROOT; }; + 5C1E45572D11D67600525864 /* bridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bridge.h; sourceTree = ""; }; 5C21D80A296C7B81005BA16D /* CombinedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombinedView.swift; sourceTree = ""; }; 5C22299D29CCB3C400F00E69 /* Clock.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Clock.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5C2229A829CCB41900F00E69 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; @@ -804,6 +807,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 5C1E45562D11D66A00525864 /* libIOReport.tbd in Frameworks */, 9A2847C22666AA8700EC1F6D /* Kit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1155,6 +1159,7 @@ 5C3068722C32E83200B05EFA /* widget.swift */, 9A97CECD2537331B00742D8F /* Info.plist */, 9A97CEFF2537340400742D8F /* config.plist */, + 5C1E45572D11D67600525864 /* bridge.h */, ); path = CPU; sourceTree = ""; @@ -1162,6 +1167,7 @@ 9A998CD622A199920087ADE7 /* Frameworks */ = { isa = PBXGroup; children = ( + 5C1E45552D11D66200525864 /* libIOReport.tbd */, 9ADE7005265D039300D2FBA8 /* IOKit.framework */, 9A97CE2A25371B2300742D8F /* IntelPowerGadget.framework */, 9A998CD922A199970087ADE7 /* ServiceManagement.framework */, @@ -1699,7 +1705,7 @@ New, ); LastSwiftUpdateCheck = 1540; - LastUpgradeCheck = 1600; + LastUpgradeCheck = 1620; ORGANIZATIONNAME = "Serhiy Mytrovtsiy"; TargetAttributes = { 5C22299C29CCB3C400F00E69 = { @@ -2850,7 +2856,6 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; - SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_VERSION = 5.0; }; name = Debug; @@ -2888,7 +2893,6 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; - SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_VERSION = 5.0; }; name = Release; @@ -3259,6 +3263,7 @@ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; + SWIFT_OBJC_BRIDGING_HEADER = Modules/CPU/bridge.h; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; USE_HEADERMAP = YES; @@ -3299,6 +3304,7 @@ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; + SWIFT_OBJC_BRIDGING_HEADER = Modules/CPU/bridge.h; SWIFT_VERSION = 5.0; USE_HEADERMAP = YES; VERSIONING_SYSTEM = "apple-generic"; diff --git a/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme b/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme index 8fb3609a398..c6d070e8e12 100644 --- a/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme +++ b/Stats.xcodeproj/xcshareddata/xcschemes/SMC.xcscheme @@ -1,6 +1,6 @@ CFBundleShortVersionString $(MARKETING_VERSION) CFBundleVersion - 641 + 642 Description Simple macOS system monitor in your menu bar LSApplicationCategoryType diff --git a/Widgets/Supporting Files/Info.plist b/Widgets/Supporting Files/Info.plist index dded827781d..f886fb7734c 100644 --- a/Widgets/Supporting Files/Info.plist +++ b/Widgets/Supporting Files/Info.plist @@ -13,7 +13,7 @@ CFBundleShortVersionString 2.11.21 CFBundleVersion - 641 + 642 NSExtension NSExtensionPointIdentifier