mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
fix: moved DispatchSource.MemoryPressureEvent to custom RAMPressure enum. Fixed the crashes on some macs (#2212)
This commit is contained in:
@@ -19,7 +19,7 @@ public class BarChart: WidgetWrapper {
|
||||
private var colors: [SColor] = SColor.allCases
|
||||
|
||||
private var _value: [[ColorValue]] = [[]]
|
||||
private var _pressureLevel: DispatchSource.MemoryPressureEvent = .normal
|
||||
private var _pressureLevel: RAMPressure = .normal
|
||||
private var _colorZones: colorZones = (0.6, 0.8)
|
||||
|
||||
private var boxSettingsView: NSSwitch? = nil
|
||||
@@ -93,7 +93,7 @@ public class BarChart: WidgetWrapper {
|
||||
super.draw(dirtyRect)
|
||||
|
||||
var value: [[ColorValue]] = []
|
||||
var pressureLevel: DispatchSource.MemoryPressureEvent = .normal
|
||||
var pressureLevel: RAMPressure = .normal
|
||||
var colorZones: colorZones = (0.6, 0.8)
|
||||
self.queue.sync {
|
||||
value = self._value
|
||||
@@ -224,7 +224,7 @@ public class BarChart: WidgetWrapper {
|
||||
})
|
||||
}
|
||||
|
||||
public func setPressure(_ newPressureLevel: DispatchSource.MemoryPressureEvent) {
|
||||
public func setPressure(_ newPressureLevel: RAMPressure) {
|
||||
guard self._pressureLevel != newPressureLevel else { return }
|
||||
self._pressureLevel = newPressureLevel
|
||||
DispatchQueue.main.async(execute: {
|
||||
|
||||
@@ -29,7 +29,7 @@ public class LineChart: WidgetWrapper {
|
||||
), num: 60)
|
||||
private var colors: [SColor] = SColor.allCases.filter({ $0 != SColor.cluster })
|
||||
private var _value: Double = 0
|
||||
private var _pressureLevel: DispatchSource.MemoryPressureEvent = .normal
|
||||
private var _pressureLevel: RAMPressure = .normal
|
||||
|
||||
private var historyNumbers: [KeyValue_p] = [
|
||||
KeyValue_t(key: "30", value: "30"),
|
||||
@@ -129,7 +129,7 @@ public class LineChart: WidgetWrapper {
|
||||
guard let context = NSGraphicsContext.current?.cgContext else { return }
|
||||
|
||||
var value: Double = 0
|
||||
var pressureLevel: DispatchSource.MemoryPressureEvent = .normal
|
||||
var pressureLevel: RAMPressure = .normal
|
||||
self.queue.sync {
|
||||
value = self._value
|
||||
pressureLevel = self._pressureLevel
|
||||
@@ -249,7 +249,7 @@ public class LineChart: WidgetWrapper {
|
||||
})
|
||||
}
|
||||
|
||||
public func setPressure(_ newPressureLevel: DispatchSource.MemoryPressureEvent) {
|
||||
public func setPressure(_ newPressureLevel: RAMPressure) {
|
||||
guard self._pressureLevel != newPressureLevel else { return }
|
||||
self._pressureLevel = newPressureLevel
|
||||
DispatchQueue.main.async(execute: {
|
||||
|
||||
@@ -15,7 +15,7 @@ public class MemoryWidget: WidgetWrapper {
|
||||
private var orderReversedState: Bool = false
|
||||
private var value: (String, String) = ("0", "0")
|
||||
private var percentage: Double = 0
|
||||
private var pressureLevel: DispatchSource.MemoryPressureEvent = .normal
|
||||
private var pressureLevel: RAMPressure = .normal
|
||||
private var symbolsState: Bool = true
|
||||
private var colorState: SColor = .monochrome
|
||||
|
||||
@@ -137,7 +137,7 @@ public class MemoryWidget: WidgetWrapper {
|
||||
})
|
||||
}
|
||||
|
||||
public func setPressure(_ newPressureLevel: DispatchSource.MemoryPressureEvent) {
|
||||
public func setPressure(_ newPressureLevel: RAMPressure) {
|
||||
guard self.pressureLevel != newPressureLevel else { return }
|
||||
self.pressureLevel = newPressureLevel
|
||||
DispatchQueue.main.async(execute: {
|
||||
|
||||
@@ -19,7 +19,7 @@ public class Mini: WidgetWrapper {
|
||||
private var colors: [SColor] = SColor.allCases
|
||||
|
||||
private var _value: Double = 0
|
||||
private var _pressureLevel: DispatchSource.MemoryPressureEvent = .normal
|
||||
private var _pressureLevel: RAMPressure = .normal
|
||||
private var _colorZones: colorZones = (0.6, 0.8)
|
||||
private var _suffix: String = "%"
|
||||
|
||||
@@ -93,7 +93,7 @@ public class Mini: WidgetWrapper {
|
||||
super.draw(dirtyRect)
|
||||
|
||||
var value: Double = 0
|
||||
var pressureLevel: DispatchSource.MemoryPressureEvent = .normal
|
||||
var pressureLevel: RAMPressure = .normal
|
||||
var colorZones: colorZones = (0.6, 0.8)
|
||||
var label: String = ""
|
||||
var suffix: String = ""
|
||||
@@ -155,7 +155,7 @@ public class Mini: WidgetWrapper {
|
||||
})
|
||||
}
|
||||
|
||||
public func setPressure(_ newPressureLevel: DispatchSource.MemoryPressureEvent) {
|
||||
public func setPressure(_ newPressureLevel: RAMPressure) {
|
||||
guard self._pressureLevel != newPressureLevel else { return }
|
||||
self._pressureLevel = newPressureLevel
|
||||
DispatchQueue.main.async(execute: {
|
||||
|
||||
@@ -74,7 +74,7 @@ public class TextWidget: WidgetWrapper {
|
||||
self.display()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
static public func parseText(_ raw: String) -> [KeyValue_t] {
|
||||
var pairs: [KeyValue_t] = []
|
||||
do {
|
||||
@@ -97,5 +97,4 @@ public class TextWidget: WidgetWrapper {
|
||||
}
|
||||
return pairs
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -394,3 +394,20 @@ extension SizeUnit: CaseIterable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum RAMPressure: String, Codable {
|
||||
case normal
|
||||
case warning
|
||||
case critical
|
||||
|
||||
func pressureColor() -> NSColor {
|
||||
switch self {
|
||||
case .normal:
|
||||
return NSColor.systemGreen
|
||||
case .warning:
|
||||
return NSColor.systemYellow
|
||||
case .critical:
|
||||
return NSColor.systemRed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,16 +26,12 @@ public struct RAM_Usage: Codable {
|
||||
var app: Double
|
||||
var cache: Double
|
||||
|
||||
var rawPressureLevel: UInt
|
||||
var swap: Swap
|
||||
var pressure: Pressure
|
||||
|
||||
public var usage: Double {
|
||||
get { Double((self.total - self.free) / self.total) }
|
||||
}
|
||||
|
||||
public var pressureLevel: DispatchSource.MemoryPressureEvent {
|
||||
DispatchSource.MemoryPressureEvent(rawValue: self.rawPressureLevel)
|
||||
}
|
||||
}
|
||||
|
||||
public struct Swap: Codable {
|
||||
@@ -44,6 +40,11 @@ public struct Swap: Codable {
|
||||
var free: Double
|
||||
}
|
||||
|
||||
public struct Pressure: Codable {
|
||||
let level: Int
|
||||
let value: RAMPressure
|
||||
}
|
||||
|
||||
public class RAM: Module {
|
||||
private let popupView: Popup
|
||||
private let settingsView: Settings
|
||||
@@ -141,10 +142,10 @@ public class RAM: Module {
|
||||
switch w.item {
|
||||
case let widget as Mini:
|
||||
widget.setValue(value.usage)
|
||||
widget.setPressure(value.pressureLevel)
|
||||
widget.setPressure(value.pressure.value)
|
||||
case let widget as LineChart:
|
||||
widget.setValue(value.usage)
|
||||
widget.setPressure(value.pressureLevel)
|
||||
widget.setPressure(value.pressure.value)
|
||||
case let widget as BarChart:
|
||||
if self.splitValueState {
|
||||
widget.setValue([[
|
||||
@@ -155,7 +156,7 @@ public class RAM: Module {
|
||||
} else {
|
||||
widget.setValue([[ColorValue(value.usage)]])
|
||||
widget.setColorZones((0.8, 0.95))
|
||||
widget.setPressure(value.pressureLevel)
|
||||
widget.setPressure(value.pressure.value)
|
||||
}
|
||||
case let widget as PieChart:
|
||||
widget.setValue([
|
||||
@@ -167,7 +168,7 @@ public class RAM: Module {
|
||||
let free = Units(bytes: Int64(value.free)).getReadableMemory()
|
||||
let used = Units(bytes: Int64(value.used)).getReadableMemory()
|
||||
widget.setValue((free, used), usedPercentage: value.usage)
|
||||
widget.setPressure(value.pressureLevel)
|
||||
widget.setPressure(value.pressure.value)
|
||||
case let widget as Tachometer:
|
||||
widget.setValue([
|
||||
circle_segment(value: value.app/total, color: self.appColor),
|
||||
@@ -175,7 +176,7 @@ public class RAM: Module {
|
||||
circle_segment(value: value.compressed/total, color: self.compressedColor)
|
||||
])
|
||||
case let widget as TextWidget:
|
||||
var text = self.textValue
|
||||
var text = "\(self.textValue)"
|
||||
let pairs = TextWidget.parseText(text)
|
||||
pairs.forEach { pair in
|
||||
var replacement: String? = nil
|
||||
@@ -203,8 +204,8 @@ public class RAM: Module {
|
||||
}
|
||||
case "$pressure":
|
||||
switch pair.value {
|
||||
case "value": replacement = value.pressureLevel.description
|
||||
case "level": replacement = value.rawPressureLevel.description
|
||||
case "level": replacement = "\(value.pressure.level)"
|
||||
case "value": replacement = value.pressure.value.rawValue
|
||||
default: return
|
||||
}
|
||||
default: return
|
||||
|
||||
@@ -127,7 +127,7 @@ class Notifications: NotificationsWrapper {
|
||||
if let threshold = thresholdPair.additional as? DispatchSource.MemoryPressureEvent {
|
||||
self.checkDouble(
|
||||
id: self.pressureID,
|
||||
value: Double(value.pressureLevel.rawValue),
|
||||
value: Double(value.pressure.level),
|
||||
threshold: Double(threshold.rawValue),
|
||||
title: title,
|
||||
subtitle: "\(localizedString("Memory pressure")): \(localizedString(thresholdPair.value))"
|
||||
|
||||
@@ -257,7 +257,7 @@ internal class Popup: PopupWrapper {
|
||||
circle_segment(value: value.compressed/value.total, color: self.compressedColor)
|
||||
])
|
||||
self.circle?.setNonActiveSegmentColor(self.freeColor)
|
||||
self.level?.setLevel(value.pressureLevel)
|
||||
self.level?.setValue(value.pressure)
|
||||
|
||||
self.initialized = true
|
||||
}
|
||||
@@ -429,7 +429,7 @@ public class PressureView: NSView {
|
||||
circle_segment(value: 1/3, color: NSColor.systemRed)
|
||||
]
|
||||
|
||||
private var level: DispatchSource.MemoryPressureEvent = .normal
|
||||
private var value: Pressure = Pressure(level: 1, value: .normal)
|
||||
|
||||
public override func draw(_ rect: CGRect) {
|
||||
let arcWidth: CGFloat = 7.0
|
||||
@@ -465,7 +465,7 @@ public class PressureView: NSView {
|
||||
let needleEndSize: CGFloat = 2
|
||||
let needlePath = NSBezierPath()
|
||||
|
||||
switch self.level {
|
||||
switch self.value.value {
|
||||
case .normal:
|
||||
needlePath.move(to: CGPoint(x: self.bounds.width * 0.15, y: self.bounds.width * 0.40))
|
||||
needlePath.line(to: CGPoint(x: self.bounds.width/2, y: self.bounds.height/2 - needleEndSize))
|
||||
@@ -478,7 +478,6 @@ public class PressureView: NSView {
|
||||
needlePath.move(to: CGPoint(x: self.bounds.width * 0.85, y: self.bounds.width * 0.40))
|
||||
needlePath.line(to: CGPoint(x: self.bounds.width/2, y: self.bounds.height/2 - needleEndSize))
|
||||
needlePath.line(to: CGPoint(x: self.bounds.width/2, y: self.bounds.height/2 + needleEndSize))
|
||||
default: break
|
||||
}
|
||||
|
||||
needlePath.close()
|
||||
@@ -501,12 +500,12 @@ public class PressureView: NSView {
|
||||
]
|
||||
|
||||
let rect = CGRect(x: (self.frame.width-6)/2, y: (self.frame.height-26)/2, width: 6, height: 12)
|
||||
let str = NSAttributedString.init(string: "\(self.level.rawValue)", attributes: stringAttributes)
|
||||
let str = NSAttributedString.init(string: "\(self.value.level)", attributes: stringAttributes)
|
||||
str.draw(with: rect)
|
||||
}
|
||||
|
||||
public func setLevel(_ level: DispatchSource.MemoryPressureEvent) {
|
||||
self.level = level
|
||||
public func setValue(_ newValue: Pressure) {
|
||||
self.value = newValue
|
||||
if self.window?.isVisible ?? true {
|
||||
self.display()
|
||||
}
|
||||
|
||||
@@ -103,11 +103,11 @@ public class Portal: PortalWrapper {
|
||||
self.usedField?.stringValue = Units(bytes: Int64(value.used)).getReadableMemory()
|
||||
self.freeField?.stringValue = Units(bytes: Int64(value.free)).getReadableMemory()
|
||||
self.swapField?.stringValue = Units(bytes: Int64(value.swap.used)).getReadableMemory()
|
||||
self.pressureLevelField?.stringValue = "\(value.pressureLevel.rawValue)"
|
||||
self.pressureLevelField?.stringValue = value.pressure.value.rawValue
|
||||
|
||||
self.usedField?.toolTip = "\(Int(value.usage.rounded(toPlaces: 2) * 100))%"
|
||||
self.freeField?.toolTip = "\(Int((1-value.usage).rounded(toPlaces: 2) * 100))%"
|
||||
if let level = memoryPressureLevels.first(where: { $0.additional as? DispatchSource.MemoryPressureEvent == value.pressureLevel }) {
|
||||
if let level = memoryPressureLevels.first(where: { $0.additional as? RAMPressure == value.pressure.value }) {
|
||||
self.pressureLevelField?.toolTip = localizedString(level.value)
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,13 @@ internal class UsageReader: Reader<RAM_Usage> {
|
||||
var pressureLevel: Int = 0
|
||||
sysctlbyname("kern.memorystatus_vm_pressure_level", &pressureLevel, &intSize, nil, 0)
|
||||
|
||||
var pressureValue: RAMPressure
|
||||
switch pressureLevel {
|
||||
case 2: pressureValue = .warning
|
||||
case 4: pressureValue = .critical
|
||||
default: pressureValue = .normal
|
||||
}
|
||||
|
||||
var stringSize: size_t = MemoryLayout<xsw_usage>.size
|
||||
var swap: xsw_usage = xsw_usage()
|
||||
sysctlbyname("vm.swapusage", &swap, &stringSize, nil, 0)
|
||||
@@ -77,13 +84,12 @@ internal class UsageReader: Reader<RAM_Usage> {
|
||||
app: used - wired - compressed,
|
||||
cache: purgeable + external,
|
||||
|
||||
rawPressureLevel: UInt(pressureLevel),
|
||||
|
||||
swap: Swap(
|
||||
total: Double(swap.xsu_total),
|
||||
used: Double(swap.xsu_used),
|
||||
free: Double(swap.xsu_avail)
|
||||
)
|
||||
),
|
||||
pressure: Pressure(level: pressureLevel, value: pressureValue)
|
||||
))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ public struct RAM_entry: TimelineEntry {
|
||||
compressed: 414629888.0,
|
||||
app: 16369778688.0,
|
||||
cache: 12575948800.0,
|
||||
rawPressureLevel: 1,
|
||||
swap: Swap(total: 0, used: 0, free: 0)
|
||||
swap: Swap(total: 0, used: 0, free: 0),
|
||||
pressure: Pressure(level: 1, value: .normal)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -110,7 +110,7 @@ public struct RAMWidget: Widget {
|
||||
HStack {
|
||||
Text(localizedString("Pressure level")).font(.system(size: 12, weight: .regular)).foregroundColor(.secondary)
|
||||
Spacer()
|
||||
Text("\(value.rawPressureLevel)")
|
||||
Text("\(value.pressure.level)")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(MARKETING_VERSION)</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>610</string>
|
||||
<string>632</string>
|
||||
<key>Description</key>
|
||||
<string>Simple macOS system monitor in your menu bar</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.11.17</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>610</string>
|
||||
<string>632</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
|
||||
Reference in New Issue
Block a user