feat: small codebase refactoring (mostly removed unused code and changes in access control)

This commit is contained in:
Serhiy Mytrovtsiy
2024-05-08 17:21:58 +02:00
parent e925e6d131
commit eb882774bb
37 changed files with 160 additions and 583 deletions

View File

@@ -24,7 +24,7 @@ public class BatteryWidget: WidgetWrapper {
private var _ACStatus: Bool = false
private var _optimizedCharging: Bool = false
public init(title: String, config: NSDictionary?, preview: Bool = false) {
public init(title: String, preview: Bool = false) {
let widgetTitle: String = title
super.init(.battery, title: widgetTitle, frame: CGRect(
@@ -449,7 +449,7 @@ public class BatteryDetailsWidget: WidgetWrapper {
private var percentage: Double? = nil
private var time: Int = 0
public init(title: String, config: NSDictionary?, preview: Bool = false) {
public init(title: String, preview: Bool = false) {
super.init(.batteryDetails, title: title, frame: CGRect(
x: Constants.Widget.margin.x,
y: Constants.Widget.margin.y,

View File

@@ -11,10 +11,10 @@
import Cocoa
public class Label: WidgetWrapper {
internal class Label: WidgetWrapper {
private var label: String
public init(title: String, config: NSDictionary, preview: Bool = false) {
internal init(title: String, config: NSDictionary) {
if let title = config["Title"] as? String {
self.label = title
} else {
@@ -56,12 +56,4 @@ public class Label: WidgetWrapper {
margin.y += size.height
}
}
public func setLabel(_ new: String) {
guard self.label != new else { return }
self.label = new
DispatchQueue.main.async(execute: {
self.needsDisplay = true
})
}
}

View File

@@ -16,10 +16,6 @@ public class Mini: WidgetWrapper {
private var colorState: Color = .monochrome
private var alignmentState: String = "left"
private var labelLayer: CATextLayer? = nil
private var valueLayer: CATextLayer? = nil
private let onlyValueWidth: CGFloat = 40
private var colors: [Color] = Color.allCases
private var _value: Double = 0

View File

@@ -13,7 +13,6 @@ import Cocoa
public class SpeedWidget: WidgetWrapper {
private var icon: String = "dots"
private var state: Bool = false
private var valueState: Bool = true
private var unitsState: Bool = true
private var monochromeState: Bool = false
@@ -28,9 +27,6 @@ public class SpeedWidget: WidgetWrapper {
private var symbols: [String] = ["U", "D"]
private var uploadField: NSTextField? = nil
private var downloadField: NSTextField? = nil
private var uploadValue: Int64 = 0
private var downloadValue: Int64 = 0
@@ -91,10 +87,6 @@ public class SpeedWidget: WidgetWrapper {
self.reverseOrderState = Store.shared.bool(key: "\(self.title)_\(self.type.rawValue)_reverseOrder", defaultValue: self.reverseOrderState)
}
if self.valueState && self.icon != "none" {
self.state = true
}
if preview {
self.downloadValue = 8947141
self.uploadValue = 478678
@@ -111,9 +103,9 @@ public class SpeedWidget: WidgetWrapper {
var width: CGFloat = 0
switch self.modeState {
case "oneRow":
width = self.drawOneRow(dirtyRect)
width = self.drawOneRow()
case "twoRows":
width = self.drawTwoRows(dirtyRect)
width = self.drawTwoRows()
default:
width = 0
}
@@ -123,7 +115,7 @@ public class SpeedWidget: WidgetWrapper {
// MARK: - one row
private func drawOneRow(_ dirtyRect: NSRect) -> CGFloat {
private func drawOneRow() -> CGFloat {
var width: CGFloat = Constants.Widget.margin.x
let downloadIconColor = self.downloadValue >= 1_024 ? self.downloadColor : self.noActivityColor
let uploadIconColor = self.uploadValue >= 1_024 ? self.uploadColor : self.noActivityColor
@@ -279,17 +271,17 @@ public class SpeedWidget: WidgetWrapper {
// MARK: - two rows
private func drawTwoRows(_ dirtyRect: NSRect) -> CGFloat {
private func drawTwoRows() -> CGFloat {
var width: CGFloat = 7
var x: CGFloat = 7
switch self.icon {
case "dots":
self.drawDots(dirtyRect)
self.drawDots()
case "arrows":
self.drawArrows(dirtyRect)
self.drawArrows()
case "chars":
self.drawChars(dirtyRect)
self.drawChars()
default:
x = 0
width = 0
@@ -335,7 +327,7 @@ public class SpeedWidget: WidgetWrapper {
return width
}
private func drawDots(_ dirtyRect: NSRect) {
private func drawDots() {
let rowHeight: CGFloat = self.frame.height / 2
let size: CGFloat = 6
let y: CGFloat = (rowHeight-size)/2
@@ -353,7 +345,7 @@ public class SpeedWidget: WidgetWrapper {
uploadCircle.fill()
}
private func drawArrows(_ dirtyRect: NSRect) {
private func drawArrows() {
let arrowAngle = CGFloat(Double.pi / 5)
let half = self.frame.size.height / 2
let scaleFactor = NSScreen.main?.backingScaleFactor ?? 1
@@ -394,7 +386,7 @@ public class SpeedWidget: WidgetWrapper {
uploadArrow.close()
}
private func drawChars(_ dirtyRect: NSRect) {
private func drawChars() {
let rowHeight: CGFloat = self.frame.height / 2
let downloadY: CGFloat = self.reverseOrderState ? rowHeight+1 : 1
let uploadY: CGFloat = self.reverseOrderState ? 1 : rowHeight+1

View File

@@ -14,7 +14,6 @@ import Cocoa
public struct Stack_t: KeyValue_p {
public var key: String
public var value: String
public var additional: Any?
var index: Int {
get {
@@ -25,10 +24,9 @@ public struct Stack_t: KeyValue_p {
}
}
public init(key: String, value: String, additional: Any? = nil) {
public init(key: String, value: String) {
self.key = key
self.value = value
self.additional = additional
}
}
@@ -280,7 +278,7 @@ private class OrderTableView: NSView, NSTableViewDelegate, NSTableViewDataSource
private let tableView = NSTableView()
private var dragDropType = NSPasteboard.PasteboardType(rawValue: "\(Bundle.main.bundleIdentifier!).sensors-row")
public var reorderCallback: () -> Void = {}
fileprivate var reorderCallback: () -> Void = {}
private let list: UnsafeMutablePointer<[Stack_t]>
init(_ list: UnsafeMutablePointer<[Stack_t]>) {
@@ -334,7 +332,7 @@ private class OrderTableView: NSView, NSTableViewDelegate, NSTableViewDataSource
NotificationCenter.default.removeObserver(self)
}
public func update() {
fileprivate func update() {
self.tableView.reloadData()
}

View File

@@ -27,7 +27,7 @@ public class Tachometer: WidgetWrapper {
private let size: CGFloat = Constants.Widget.height - (Constants.Widget.margin.y*2) + (Constants.Widget.margin.x*2)
public init(title: String, config: NSDictionary?, preview: Bool = false) {
public init(title: String, preview: Bool = false) {
let widgetTitle: String = title
super.init(.tachometer, title: widgetTitle, frame: CGRect(

View File

@@ -24,17 +24,6 @@ extension String: LocalizedError {
return size.width
}
public func heightOfString(usingFont font: NSFont) -> CGFloat {
let fontAttributes = [NSAttributedString.Key.font: font]
let size = self.size(withAttributes: fontAttributes)
return size.height
}
public func sizeOfString(usingFont font: NSFont) -> CGSize {
let fontAttributes = [NSAttributedString.Key.font: font]
return self.size(withAttributes: fontAttributes)
}
public func condenseWhitespace() -> String {
let components = self.components(separatedBy: .whitespacesAndNewlines)
return components.filter { !$0.isEmpty }.joined(separator: " ")
@@ -162,21 +151,6 @@ public extension Double {
}
}
func percentageColor(color: Bool) -> NSColor {
if !color {
return NSColor.textColor
}
switch self {
case 0.6...0.8:
return NSColor.systemOrange
case 0.8...1:
return NSColor.systemRed
default:
return NSColor.systemGreen
}
}
func batteryColor(color: Bool = false, lowPowerMode: Bool? = nil) -> NSColor {
if let mode = lowPowerMode, mode {
return NSColor.systemOrange
@@ -442,17 +416,6 @@ public extension NSColor {
}
}
public extension CATransaction {
static func disableAnimations(_ closure: () -> Void) {
CATransaction.begin()
CATransaction.setDisableActions(true)
CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions)
CATransaction.setAnimationDuration(0)
closure()
CATransaction.commit()
}
}
public class FlippedStackView: NSStackView {
public override var isFlipped: Bool { return true }
}
@@ -550,9 +513,6 @@ public extension Data {
var socketAddress: sockaddr {
return withUnsafeBytes { $0.load(as: sockaddr.self) }
}
var socketAddressInternet: sockaddr_in {
return withUnsafeBytes { $0.load(as: sockaddr_in.self) }
}
}
public extension Date {

View File

@@ -92,7 +92,6 @@ extension LaunchAtLogin: DeprecationWarningWorkaround {
public protocol KeyValue_p {
var key: String { get }
var value: String { get }
var additional: Any? { get }
}
public struct KeyValue_t: KeyValue_p, Codable {
@@ -431,15 +430,6 @@ public func portalWithColorRow(_ v: NSStackView, color: NSColor, title: String)
return (colorView, valueView)
}
public extension Array where Element: Equatable {
func allEqual() -> Bool {
if let firstElem = first {
return !dropFirst().contains { $0 != firstElem }
}
return true
}
}
public extension Array where Element: Hashable {
func difference(from other: [Element]) -> [Element] {
let thisSet = Set(self)
@@ -448,22 +438,6 @@ public extension Array where Element: Hashable {
}
}
public func findAndToggleNSControlState(_ view: NSView?, state: NSControl.StateValue) {
if let control = view?.subviews.first(where: { $0 is NSControl && !($0 is NSTextField) }) {
toggleNSControlState(control as? NSControl, state: state)
}
}
public func findAndToggleEnableNSControlState(_ view: NSView?, state: Bool) {
if let control = view?.subviews.first(where: { ($0 is NSControl || $0 is NSPopUpButton) && !($0 is NSTextField) }) {
if control is NSControl {
toggleEnableNSControlState(control as? NSControl, state: state)
} else if control is NSPopUpButton {
toggleEnableNSControlState(control as? NSPopUpButton, state: state)
}
}
}
public func toggleNSControlState(_ control: NSControl?, state: NSControl.StateValue) {
if #available(OSX 10.15, *) {
if let checkbox = control as? NSSwitch {
@@ -476,30 +450,6 @@ public func toggleNSControlState(_ control: NSControl?, state: NSControl.StateVa
}
}
public func toggleEnableNSControlState(_ control: NSControl?, state: Bool) {
if #available(OSX 10.15, *) {
if let checkbox = control as? NSSwitch {
checkbox.isEnabled = state
} else if let checkbox = control as? NSPopUpButton {
checkbox.isEnabled = state
}
} else {
if let checkbox = control as? NSButton {
checkbox.isEnabled = state
}
}
}
public func dialogOKCancel(question: String, text: String) {
let alert = NSAlert()
alert.messageText = question
alert.informativeText = text
alert.alertStyle = .warning
alert.addButton(withTitle: "OK")
alert.addButton(withTitle: "Cancel")
alert.runModal()
}
public func asyncShell(_ args: String) {
let task = Process()
task.launchPath = "/bin/sh"
@@ -657,21 +607,6 @@ public struct TopProcess: Codable, Process_p {
}
}
public func getIOParent(_ obj: io_registry_entry_t) -> io_registry_entry_t? {
var parent: io_registry_entry_t = 0
if IORegistryEntryGetParentEntry(obj, kIOServicePlane, &parent) != KERN_SUCCESS {
return nil
}
if IOObjectConformsTo(parent, "IOBlockStorageDriver") == 0 {
IOObjectRelease(parent)
return nil
}
return parent
}
public func fetchIOService(_ name: String) -> [NSDictionary]? {
var iterator: io_iterator_t = io_iterator_t()
var obj: io_registry_entry_t = 1
@@ -709,7 +644,7 @@ public func getIOProperties(_ entry: io_registry_entry_t) -> NSDictionary? {
return properties?.takeUnretainedValue()
}
public func getIOName(_ entry: io_registry_entry_t) -> String? {
internal func getIOName(_ entry: io_registry_entry_t) -> String? {
let pointer = UnsafeMutablePointer<io_name_t>.allocate(capacity: 1)
let result = IORegistryEntryGetName(entry, pointer)
@@ -721,29 +656,6 @@ public func getIOName(_ entry: io_registry_entry_t) -> String? {
return String(cString: UnsafeRawPointer(pointer).assumingMemoryBound(to: CChar.self))
}
public func getIOChildrens(_ entry: io_registry_entry_t) -> [String]? {
var iter: io_iterator_t = io_iterator_t()
if IORegistryEntryGetChildIterator(entry, kIOServicePlane, &iter) != kIOReturnSuccess {
return nil
}
var iterator: io_registry_entry_t = 1
var list: [String] = []
while iterator != 0 {
iterator = IOIteratorNext(iter)
let pointer = UnsafeMutablePointer<io_name_t>.allocate(capacity: 1)
if IORegistryEntryGetName(iterator, pointer) != kIOReturnSuccess {
continue
}
list.append(String(cString: UnsafeRawPointer(pointer).assumingMemoryBound(to: CChar.self)))
IOObjectRelease(iterator)
}
return list
}
public class ColorView: NSView {
public var inactiveColor: NSColor = NSColor.lightGray.withAlphaComponent(0.75)
@@ -834,38 +746,10 @@ public func sysctlByName(_ name: String) -> Int64 {
return num
}
public class CAText: CATextLayer {
public init(fontSize: CGFloat = 12, weight: NSFont.Weight = .regular) {
super.init()
self.font = NSFont.systemFont(ofSize: fontSize, weight: weight)
self.fontSize = fontSize
self.allowsFontSubpixelQuantization = true
self.contentsScale = NSScreen.main?.backingScaleFactor ?? 1
self.rasterizationScale = NSScreen.main?.backingScaleFactor ?? 1
self.foregroundColor = NSColor.textColor.cgColor
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override init(layer: Any) {
super.init(layer: layer)
}
public func getWidth(add: CGFloat = 0) -> CGFloat {
let value = self.string as? String ?? ""
return value.widthOfString(usingFont: self.font as! NSFont).rounded(.up) + add
}
}
public class WidgetLabelView: NSView {
internal class WidgetLabelView: NSView {
private var title: String
public init(_ title: String, height: CGFloat) {
internal init(_ title: String, height: CGFloat) {
self.title = title
super.init(frame: NSRect(
@@ -905,32 +789,6 @@ public class WidgetLabelView: NSView {
}
}
public func isRoot() -> Bool {
return getuid() == 0
}
public func ensureRoot() {
if isRoot() {
return
}
let pwd = Bundle.main.bundleURL.absoluteString.replacingOccurrences(of: "file://", with: "")
guard let script = NSAppleScript(source: "do shell script \"\(pwd)/Contents/MacOS/Stats > /dev/null 2>&1 &\" with administrator privileges") else {
return
}
var err: NSDictionary? = nil
script.executeAndReturnError(&err)
if err != nil {
print("cannot run script as root: \(String(describing: err))")
return
}
NSApp.terminate(nil)
return
}
public func process(path: String, arguments: [String]) -> String? {
let task = Process()
task.launchPath = path
@@ -999,13 +857,6 @@ public class SMCHelper {
}
}
public func powermetrics(_ samplers: [String], completion: @escaping (String?) -> Void) {
guard let helper = self.helper(nil) else { return }
helper.powermetrics(samplers) { result in
completion(result)
}
}
public func isActive() -> Bool {
return self.connection != nil
}
@@ -1187,13 +1038,13 @@ public class EmptyView: NSStackView {
}
}
public func saveNSStatusItemPosition(id: String) {
internal func saveNSStatusItemPosition(id: String) {
let position = Store.shared.int(key: "NSStatusItem Preferred Position \(id)", defaultValue: -1)
if position != -1 {
Store.shared.set(key: "NSStatusItem Restore Position \(id)", value: position)
}
}
public func restoreNSStatusItemPosition(id: String) {
internal func restoreNSStatusItemPosition(id: String) {
let prevPosition = Store.shared.int(key: "NSStatusItem Restore Position \(id)", defaultValue: -1)
if prevPosition != -1 {
Store.shared.set(key: "NSStatusItem Preferred Position \(id)", value: prevPosition)
@@ -1418,7 +1269,7 @@ public class PreferencesSection: NSStackView {
}
}
public class PreferencesSeparator: NSView {
private class PreferencesSeparator: NSView {
public init() {
super.init(frame: .zero)
self.wantsLayer = true
@@ -1601,7 +1452,6 @@ public class PreferencesSwitch: NSStackView {
self.spacing = Constants.Settings.margin
let btn = switchView(action: #selector(self.callback), state: state)
with.widthAnchor.constraint(equalToConstant: 68).isActive = true
with.isEnabled = state
self.addArrangedSubview(NSView())

View File

@@ -8,18 +8,6 @@
import Cocoa
public protocol Module_p {
var available: Bool { get }
var enabled: Bool { get }
var settings: Settings_p? { get }
func mount()
func unmount()
func terminate()
}
public struct module_c {
public var name: String = ""
public var icon: NSImage?
@@ -75,7 +63,7 @@ public struct module_c {
}
}
open class Module: Module_p {
open class Module {
public var config: module_c
public var available: Bool = false
@@ -155,7 +143,6 @@ open class Module: Module_p {
self.settings = Settings(
config: &self.config,
widgets: &self.menuBar.widgets,
enabled: self.enabled,
moduleSettings: self.settingsView,
popupSettings: self.popupView,
notificationsSettings: self.notificationsView
@@ -232,13 +219,6 @@ open class Module: Module_p {
self.readers = list.filter({ $0 != nil }).map({ $0! as Reader_p })
}
// replace a popup view
public func replacePopup(_ view: Popup_p) {
self.popup?.setIsVisible(false)
self.popupView = view
self.popup = PopupWindow(title: self.config.name, view: self.popupView, visibilityCallback: self.visibilityCallback)
}
// determine if module is available (can be overrided in module)
open func isAvailable() -> Bool { return true }
@@ -257,9 +237,6 @@ open class Module: Module_p {
}
}
// call after widget set up
open func widgetDidSet(_ type: widget_t) {}
// call when popup appear/disappear
private func visibilityCallback(_ state: Bool) {
self.readers.filter{ $0.popup }.forEach { (reader: Reader_p) in
@@ -339,7 +316,7 @@ open class Module: Module_p {
}
}
@objc private func listenForMouseDownInSettings(_ notification: Notification) {
@objc private func listenForMouseDownInSettings() {
if let popup = self.popup, popup.isVisible && !popup.locked {
self.popup?.setIsVisible(false)
}

View File

@@ -77,7 +77,7 @@ public class PopupWindow: NSWindow, NSWindowDelegate {
}
internal class PopupViewController: NSViewController {
public var visibilityCallback: (_ state: Bool) -> Void = {_ in }
fileprivate var visibilityCallback: (_ state: Bool) -> Void = {_ in }
private var popup: PopupView
public init() {
@@ -112,19 +112,18 @@ internal class PopupViewController: NSViewController {
self.visibilityCallback(false)
}
public func setup(title: String, view: Popup_p?) {
fileprivate func setup(title: String, view: Popup_p?) {
self.title = title
self.popup.setTitle(title)
self.popup.setView(view)
}
public func setCloseButton(_ state: Bool) {
fileprivate func setCloseButton(_ state: Bool) {
self.popup.setCloseButton(state)
}
}
internal class PopupView: NSView {
private var title: String? = nil
private var view: Popup_p? = nil
private var foreground: NSVisualEffectView
@@ -190,7 +189,7 @@ internal class PopupView: NSView {
self.background.layer?.backgroundColor = self.isDarkMode ? .clear : NSColor.white.cgColor
}
public func setView(_ view: Popup_p?) {
fileprivate func setView(_ view: Popup_p?) {
self.view = view
var isScrollVisible: Bool = false
@@ -226,12 +225,11 @@ internal class PopupView: NSView {
}
}
public func setTitle(_ newTitle: String) {
self.title = newTitle
fileprivate func setTitle(_ newTitle: String) {
self.header.setTitle(newTitle)
}
public func setCloseButton(_ state: Bool) {
fileprivate func setCloseButton(_ state: Bool) {
self.header.setCloseButton(state)
}
@@ -299,7 +297,6 @@ internal class PopupView: NSView {
internal class HeaderView: NSStackView {
private var titleView: NSTextField? = nil
private var activityButton: NSButton?
private var settingsButton: NSButton?
private var title: String = ""
private var isCloseAction: Bool = false
@@ -355,7 +352,6 @@ internal class HeaderView: NSStackView {
settings.target = self
settings.toolTip = localizedString("Open module settings")
settings.focusRingType = .none
self.settingsButton = settings
self.addArrangedSubview(activity)
self.addArrangedSubview(title)
@@ -372,7 +368,7 @@ internal class HeaderView: NSStackView {
fatalError("init(coder:) has not been implemented")
}
public func setTitle(_ newTitle: String) {
fileprivate func setTitle(_ newTitle: String) {
self.title = newTitle
self.titleView?.stringValue = localizedString(newTitle)
}
@@ -388,12 +384,12 @@ internal class HeaderView: NSStackView {
line.stroke()
}
@objc func openActivityMonitor(_ sender: Any) {
@objc func openActivityMonitor() {
guard let app = self.app else { return }
NSWorkspace.shared.open([], withApplicationAt: app, configuration: NSWorkspace.OpenConfiguration())
}
@objc func openSettings(_ sender: Any) {
@objc func openSettings() {
NotificationCenter.default.post(name: .toggleSettings, object: nil, userInfo: ["module": self.title])
}
@@ -403,7 +399,7 @@ internal class HeaderView: NSStackView {
return
}
public func setCloseButton(_ state: Bool) {
fileprivate func setCloseButton(_ state: Bool) {
if state && !self.isCloseAction {
self.activityButton?.image = Bundle(for: type(of: self)).image(forResource: "close")!
self.activityButton?.toolTip = localizedString("Close popup")

View File

@@ -17,7 +17,6 @@ public protocol Portal_p: NSView {
open class PortalWrapper: NSStackView, Portal_p {
public var name: String
private let header: PortalHeader
public init(_ type: ModuleType, height: CGFloat = Constants.Popup.portalHeight) {
@@ -102,7 +101,7 @@ public class PortalHeader: NSStackView {
fatalError("init(coder:) has not been implemented")
}
@objc private func openSettings(_ sender: Any) {
@objc private func openSettings() {
self.window?.setIsVisible(false)
NotificationCenter.default.post(name: .toggleSettings, object: nil, userInfo: ["module": self.name])
}

View File

@@ -11,10 +11,6 @@
import Cocoa
public protocol value_t {
var widgetValue: Double { get }
}
public protocol Reader_p {
var optional: Bool { get }
var popup: Bool { get }
@@ -60,7 +56,6 @@ open class Reader<T: Codable>: NSObject, ReaderInternal_p {
private let module: ModuleType
private var history: Bool
private var repeatTask: Repeater?
private var nilCallbackCounter: Int = 0
private var locked: Bool = true
private var initlizalized: Bool = false

View File

@@ -16,7 +16,6 @@ public protocol Settings_p: NSView {
}
public protocol Settings_v: NSView {
var callback: (() -> Void) { get set }
func load(widgets: [widget_t])
}
@@ -58,7 +57,7 @@ open class Settings: NSStackView, Settings_p {
private var isPopupSettingsAvailable: Bool
private var isNotificationsSettingsAvailable: Bool
init(config: UnsafePointer<module_c>, widgets: UnsafeMutablePointer<[Widget]>, enabled: Bool, moduleSettings: Settings_v?, popupSettings: Popup_p?, notificationsSettings: NotificationsWrapper?) {
init(config: UnsafePointer<module_c>, widgets: UnsafeMutablePointer<[Widget]>, moduleSettings: Settings_v?, popupSettings: Popup_p?, notificationsSettings: NotificationsWrapper?) {
self.config = config
self.widgets = widgets.pointee
self.moduleSettings = moduleSettings
@@ -271,7 +270,7 @@ open class Settings: NSStackView, Settings_p {
}
}
class WidgetSelectorView: NSStackView {
private class WidgetSelectorView: NSStackView {
private var module: String
private var stateCallback: () -> Void = {}
private var moved: Bool = false
@@ -286,7 +285,7 @@ class WidgetSelectorView: NSStackView {
return view
}()
public init(module: String, widgets: [Widget], stateCallback: @escaping () -> Void) {
fileprivate init(module: String, widgets: [Widget], stateCallback: @escaping () -> Void) {
self.module = module
self.stateCallback = stateCallback
@@ -465,7 +464,7 @@ class WidgetSelectorView: NSStackView {
}
}
internal class WidgetPreview: NSStackView {
private class WidgetPreview: NSStackView {
private var stateCallback: (_ status: Bool) -> Void = {_ in }
private let rgbImage: NSImage
@@ -475,12 +474,12 @@ internal class WidgetPreview: NSStackView {
private var state: Bool
private let id: String
public var position: Int {
fileprivate var position: Int {
get { Store.shared.int(key: "\(self.id)_position", defaultValue: 0) }
set { Store.shared.set(key: "\(self.id)_position", value: newValue) }
}
public init(id: String, type: widget_t, image: NSImage, isActive: Bool, _ callback: @escaping (_ status: Bool) -> Void) {
fileprivate init(id: String, type: widget_t, image: NSImage, isActive: Bool, _ callback: @escaping (_ status: Bool) -> Void) {
self.id = id
self.stateCallback = callback
self.rgbImage = image
@@ -531,7 +530,7 @@ internal class WidgetPreview: NSStackView {
fatalError("init(coder:) has not been implemented")
}
public func status(_ newState: Bool) {
fileprivate func status(_ newState: Bool) {
self.state = newState
self.stateCallback(newState)
self.imageView.image = newState ? self.rgbImage : self.grayImage
@@ -555,8 +554,8 @@ internal class WidgetPreview: NSStackView {
}
}
internal class WidgetSettings: NSStackView {
public init(title: String, image: NSImage, settingsView: NSView) {
private class WidgetSettings: NSStackView {
fileprivate init(title: String, image: NSImage, settingsView: NSView) {
super.init(frame: NSRect.zero)
self.translatesAutoresizingMaskIntoConstraints = false

View File

@@ -54,11 +54,11 @@ public enum widget_t: String {
preview = SpeedWidget(title: module, config: widgetConfig, preview: true)
item = SpeedWidget(title: module, config: widgetConfig, preview: false)
case .battery:
preview = BatteryWidget(title: module, config: widgetConfig, preview: true)
item = BatteryWidget(title: module, config: widgetConfig, preview: false)
preview = BatteryWidget(title: module, preview: true)
item = BatteryWidget(title: module, preview: false)
case .batteryDetails:
preview = BatteryDetailsWidget(title: module, config: widgetConfig, preview: true)
item = BatteryDetailsWidget(title: module, config: widgetConfig, preview: false)
preview = BatteryDetailsWidget(title: module, preview: true)
item = BatteryDetailsWidget(title: module, preview: false)
case .stack:
preview = StackWidget(title: module, config: widgetConfig, preview: true)
item = StackWidget(title: module, config: widgetConfig, preview: false)
@@ -66,11 +66,11 @@ public enum widget_t: String {
preview = MemoryWidget(title: module, config: widgetConfig, preview: true)
item = MemoryWidget(title: module, config: widgetConfig, preview: false)
case .label:
preview = Label(title: module, config: widgetConfig, preview: true)
item = Label(title: module, config: widgetConfig, preview: false)
preview = Label(title: module, config: widgetConfig)
item = Label(title: module, config: widgetConfig)
case .tachometer:
preview = Tachometer(title: module, config: widgetConfig, preview: true)
item = Tachometer(title: module, config: widgetConfig, preview: false)
preview = Tachometer(title: module, preview: true)
item = Tachometer(title: module, preview: false)
case .state:
preview = StateWidget(title: module, config: widgetConfig, preview: true)
item = StateWidget(title: module, config: widgetConfig, preview: false)
@@ -144,21 +144,15 @@ public enum widget_t: String {
extension widget_t: CaseIterable {}
public protocol widget_p: NSView {
var type: widget_t { get }
var title: String { get }
var position: Int { get set }
var widthHandler: (() -> Void)? { get set }
var onClick: (() -> Void)? { get set }
func setValues(_ values: [value_t])
func settings() -> NSView
}
open class WidgetWrapper: NSView, widget_p {
public var type: widget_t
public var title: String
public var position: Int = -1
public var widthHandler: (() -> Void)? = nil
public var onClick: (() -> Void)? = nil
public var shadowSize: CGSize
@@ -214,10 +208,7 @@ open class WidgetWrapper: NSView, widget_p {
return width
}
// MARK: - stubs
open func settings() -> NSView { return NSView() }
open func setValues(_ values: [value_t]) {}
open override func mouseDown(with event: NSEvent) {
if let f = self.onClick {
@@ -273,7 +264,6 @@ public class Widget {
}
}
private var config: NSDictionary = NSDictionary()
private var menuBarItem: NSStatusItem? = nil
private var originX: CGFloat
@@ -363,7 +353,7 @@ public class Widget {
}
}
@objc private func togglePopup(_ sender: Any) {
@objc private func togglePopup() {
if let item = self.menuBarItem, let window = item.button?.window {
NotificationCenter.default.post(name: .togglePopup, object: nil, userInfo: [
"module": self.module,
@@ -517,7 +507,7 @@ public class MenuBar {
self.callback?()
}
@objc private func togglePopup(_ sender: NSEvent) {
@objc private func togglePopup() {
if let item = self.menuBarItem, let window = item.button?.window {
NotificationCenter.default.post(name: .togglePopup, object: nil, userInfo: [
"module": self.moduleName,

View File

@@ -21,7 +21,7 @@ public struct circle_segment {
}
}
public func scaleValue(scale: Scale = .linear, value: Double, maxValue: Double, maxHeight: CGFloat, limit: Double) -> CGFloat {
internal func scaleValue(scale: Scale = .linear, value: Double, maxValue: Double, maxHeight: CGFloat, limit: Double) -> CGFloat {
var value = value
if scale == .none && value > 1 && maxValue != 0 {
value /= maxValue
@@ -375,8 +375,6 @@ public class LineChartView: NSView {
}
public class NetworkChartView: NSView {
public var id: String = UUID().uuidString
public var base: DataSizeBase = .byte
private var reversedOrder: Bool
@@ -460,8 +458,6 @@ public class NetworkChartView: NSView {
}
public class PieChartView: NSView {
public var id: String = UUID().uuidString
private var filled: Bool = false
private var drawValue: Bool = false
private var nonActiveSegmentColor: NSColor = NSColor.lightGray
@@ -633,11 +629,11 @@ public class HalfCircleGraphView: NSView {
}
}
public class TachometerGraphView: NSView {
internal class TachometerGraphView: NSView {
private var filled: Bool
private var segments: [circle_segment]
public init(frame: NSRect, segments: [circle_segment], filled: Bool = true) {
internal init(frame: NSRect, segments: [circle_segment], filled: Bool = true) {
self.filled = filled
self.segments = segments
@@ -682,14 +678,14 @@ public class TachometerGraphView: NSView {
}
}
public func setSegments(_ segments: [circle_segment]) {
internal func setSegments(_ segments: [circle_segment]) {
self.segments = segments
if self.window?.isVisible ?? false {
self.display()
}
}
public func setFrame(_ frame: NSRect) {
internal func setFrame(_ frame: NSRect) {
var original = self.frame
original = frame
self.frame = original

View File

@@ -92,19 +92,6 @@ public class DB {
return self.values[key] as? T
}
public func findMany<T: Decodable>(_ type: T.Type, key: String) -> [T] {
guard let values = self.lldb?.findMany(key) as? [String] else { return [] }
var list: [T] = []
values.forEach({ value in
if let value = try? JSONDecoder().decode(type, from: Data(value.utf8)) {
list.append(value)
}
})
return list
}
private func clean(_ key: String) {
guard let keys = self.lldb?.keys(key) as? [String] else { return }
let maxLiveTS = Date().currentTimeSeconds() - self.ttl

View File

@@ -21,7 +21,6 @@ public class Reachability {
private var isRunning = false
private var reachability: SCNetworkReachability?
private let reachabilitySerialQueue = DispatchQueue(label: "eu.exelban.ReachabilityQueue")
private let log: NextLog = NextLog.shared.copy(category: "Reachability")
public init(start: Bool = false) {
var zeroAddress = sockaddr()

View File

@@ -11,18 +11,18 @@
import Foundation
public enum State {
private enum RepeaterState {
case paused
case running
}
public class Repeater {
internal class Repeater {
private var callback: (() -> Void)
private var state: State = .paused
private var state: RepeaterState = .paused
private var timer: DispatchSourceTimer = DispatchSource.makeTimerSource(queue: DispatchQueue(label: "eu.exelban.Stats.Repeater", qos: .default))
public init(seconds: Int, callback: @escaping (() -> Void)) {
internal init(seconds: Int, callback: @escaping (() -> Void)) {
self.callback = callback
self.setupTimer(seconds)
}
@@ -43,21 +43,21 @@ public class Repeater {
}
}
public func start() {
internal func start() {
guard self.state == .paused else { return }
self.timer.resume()
self.state = .running
}
public func pause() {
internal func pause() {
guard self.state == .running else { return }
self.timer.suspend()
self.state = .paused
}
public func reset(seconds: Int, restart: Bool = false) {
internal func reset(seconds: Int, restart: Bool = false) {
if self.state == .running {
self.pause()
}

View File

@@ -80,7 +80,6 @@ public struct os_s {
public struct core_s {
public var id: Int32
public var name: String
public var type: coreType
}
@@ -112,17 +111,10 @@ public struct gpu_s {
public var cores: Int? = nil
}
public struct disk_s {
public let name: String
public let model: String
public let size: Int64
}
public struct info_s {
public var cpu: cpu_s? = nil
public var ram: ram_s? = nil
public var gpu: [gpu_s]? = nil
public var disk: disk_s? = nil
}
public struct device_s {
@@ -139,7 +131,6 @@ public class SystemKit {
public static let shared = SystemKit()
public var device: device_s = device_s()
private let log: NextLog = NextLog.shared.copy(category: "SystemKit")
public init() {
let (modelID, serialNumber) = self.modelAndSerialNumber()
@@ -171,7 +162,6 @@ public class SystemKit {
self.device.info.cpu = self.getCPUInfo()
self.device.info.ram = self.getRamInfo()
self.device.info.gpu = self.getGPUInfo()
self.device.info.disk = self.getDiskInfo()
if let name = self.device.info.cpu?.name?.lowercased() {
if name.contains("intel") {
@@ -354,7 +344,7 @@ public class SystemKit {
return pointer.load(as: Int32.self)
}
list.append(core_s(id: id ?? -1, name: name, type: type))
list.append(core_s(id: id ?? -1, type: type))
} else if name.trimmed == "cpus" {
eCores = (props.object(forKey: "e-core-count") as? Data)?.withUnsafeBytes { pointer in
return pointer.load(as: Int32.self)
@@ -410,51 +400,6 @@ public class SystemKit {
return list
}
private func getDiskInfo() -> disk_s? {
var disk: DADisk? = nil
let keys: [URLResourceKey] = [.volumeNameKey]
let paths = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: keys)!
if let session = DASessionCreate(kCFAllocatorDefault) {
for url in paths where url.pathComponents.count == 1 {
disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, url as CFURL)
}
}
if disk == nil {
error("empty disk after fetching list")
return nil
}
if let diskDescription = DADiskCopyDescription(disk!) {
if let dict = diskDescription as? [String: AnyObject] {
if let removable = dict[kDADiskDescriptionMediaRemovableKey as String] {
if removable as! Bool {
return nil
}
}
var name: String = ""
var model: String = ""
var size: Int64 = 0
if let mediaName = dict[kDADiskDescriptionMediaNameKey as String] {
name = mediaName as! String
}
if let deviceModel = dict[kDADiskDescriptionDeviceModelKey as String] {
model = (deviceModel as! String).trimmingCharacters(in: .whitespacesAndNewlines)
}
if let mediaSize = dict[kDADiskDescriptionMediaSizeKey as String] {
size = Int64(truncating: mediaSize as! NSNumber)
}
return disk_s(name: name, model: model, size: size)
}
}
return nil
}
public func getRamInfo() -> ram_s? {
guard let res = process(path: "/usr/sbin/system_profiler", arguments: ["SPMemoryDataType", "-json"]) else {
return nil

View File

@@ -26,7 +26,7 @@ public struct version_s {
}
}
public struct Version {
internal struct Version {
var major: Int = 0
var minor: Int = 0
var patch: Int = 0

View File

@@ -231,17 +231,7 @@ public class ProcessView: NSStackView {
self.setLock(!self.lock)
}
public func set(_ process: Process_p, _ value: String) {
if self.lock && process.pid != self.pid { return }
self.labelView.stringValue = process.name
self.valueViews.first?.stringValue = value
self.imageView.image = process.icon
self.pid = process.pid
self.toolTip = "pid: \(process.pid)"
}
public func set(_ process: Process_p, _ values: [String]) {
fileprivate func set(_ process: Process_p, _ values: [String]) {
if self.lock && process.pid != self.pid { return }
self.labelView.stringValue = process.name
@@ -251,7 +241,7 @@ public class ProcessView: NSStackView {
self.toolTip = "pid: \(process.pid)"
}
public func clear(_ symbol: String = "") {
fileprivate func clear(_ symbol: String = "") {
self.labelView.stringValue = symbol
self.valueViews.forEach({ $0.stringValue = symbol })
self.imageView.image = nil
@@ -260,7 +250,7 @@ public class ProcessView: NSStackView {
self.toolTip = symbol
}
public func setLock(_ state: Bool) {
fileprivate func setLock(_ state: Bool) {
self.lock = state
if self.lock {
self.imageView.isHidden = true
@@ -273,7 +263,7 @@ public class ProcessView: NSStackView {
}
}
@objc public func kill() {
@objc private func kill() {
if let pid = self.pid {
asyncShell("kill \(pid)")
}

View File

@@ -96,20 +96,20 @@ public let SpeedBase: [KeyValue_t] = [
KeyValue_t(key: "byte", value: "Byte", additional: DataSizeBase.byte)
]
public enum StackMode: String {
internal enum StackMode: String {
case auto = "automatic"
case oneRow = "oneRow"
case twoRows = "twoRows"
}
public let SensorsWidgetMode: [KeyValue_t] = [
internal let SensorsWidgetMode: [KeyValue_t] = [
KeyValue_t(key: StackMode.auto.rawValue, value: "Automatic"),
KeyValue_t(key: "separator", value: "separator"),
KeyValue_t(key: StackMode.oneRow.rawValue, value: "One row"),
KeyValue_t(key: StackMode.twoRows.rawValue, value: "Two rows")
]
public let SpeedPictogram: [KeyValue_t] = [
internal let SpeedPictogram: [KeyValue_t] = [
KeyValue_t(key: "none", value: "None"),
KeyValue_t(key: "separator", value: "separator"),
KeyValue_t(key: "dots", value: "Dots"),
@@ -117,7 +117,7 @@ public let SpeedPictogram: [KeyValue_t] = [
KeyValue_t(key: "chars", value: "Characters")
]
public let BatteryAdditionals: [KeyValue_t] = [
internal let BatteryAdditionals: [KeyValue_t] = [
KeyValue_t(key: "none", value: "None"),
KeyValue_t(key: "separator", value: "separator"),
KeyValue_t(key: "innerPercentage", value: "Percentage inside the icon"),
@@ -128,7 +128,7 @@ public let BatteryAdditionals: [KeyValue_t] = [
KeyValue_t(key: "timeAndPercentage", value: "Time and percentage")
]
public let BatteryInfo: [KeyValue_t] = [
internal let BatteryInfo: [KeyValue_t] = [
KeyValue_t(key: "percentage", value: "Percentage"),
KeyValue_t(key: "time", value: "Time"),
KeyValue_t(key: "percentageAndTime", value: "Percentage and time"),
@@ -143,13 +143,12 @@ public let ShortLong: [KeyValue_t] = [
public let ReaderUpdateIntervals: [Int] = [1, 2, 3, 5, 10, 15, 30, 60]
public let NumbersOfProcesses: [Int] = [0, 3, 5, 8, 10, 15]
public typealias Bandwidth = (upload: Int64, download: Int64)
public let NetworkReaders: [KeyValue_t] = [
KeyValue_t(key: "interface", value: "Interface based"),
KeyValue_t(key: "process", value: "Processes based")
]
public let Alignments: [KeyValue_t] = [
internal let Alignments: [KeyValue_t] = [
KeyValue_t(key: "left", value: "Left alignment", additional: NSTextAlignment.left),
KeyValue_t(key: "center", value: "Center alignment", additional: NSTextAlignment.center),
KeyValue_t(key: "right", value: "Right alignment", additional: NSTextAlignment.right)
@@ -226,19 +225,14 @@ extension Color: CaseIterable {
]
}
public static var random: Color {
Color.allColors[.random(in: 0...Color.allColors.count)]
}
public static func fromString(_ key: String, defaultValue: Color = .systemAccent) -> Color {
return Color.allCases.first{ $0.key == key } ?? defaultValue
}
}
public class MonochromeColor {
static public let base: NSColor = NSColor.textColor
static public let red: NSColor = NSColor(red: (145), green: (145), blue: (145), alpha: 1)
static public let blue: NSColor = NSColor(red: (113), green: (113), blue: (113), alpha: 1)
internal class MonochromeColor {
static internal let red: NSColor = NSColor(red: (145), green: (145), blue: (145), alpha: 1)
static internal let blue: NSColor = NSColor(red: (113), green: (113), blue: (113), alpha: 1)
}
public typealias colorZones = (orange: Double, red: Double)
@@ -295,7 +289,6 @@ public let notificationLevels: [KeyValue_t] = [
public struct Scale: KeyValue_p, Equatable {
public let key: String
public let value: String
public var additional: Any?
public static func == (lhs: Scale, rhs: Scale) -> Bool {
return lhs.key == rhs.key
@@ -341,7 +334,6 @@ public var LineChartHistory: [KeyValue_p] = [
public struct SizeUnit: KeyValue_p, Equatable {
public let key: String
public let value: String
public var additional: Any?
public static func == (lhs: SizeUnit, rhs: SizeUnit) -> Bool {
return lhs.key == rhs.key

View File

@@ -13,7 +13,7 @@ import Cocoa
import Kit
import IOKit.ps
struct Battery_Usage: value_t, Codable {
struct Battery_Usage: Codable {
var powerSource: String = ""
var state: String? = nil
var isCharged: Bool = false
@@ -37,12 +37,6 @@ struct Battery_Usage: value_t, Codable {
var timeToEmpty: Int = 0
var timeToCharge: Int = 0
var timeOnACPower: Date? = nil
public var widgetValue: Double {
get {
return self.level
}
}
}
public class Battery: Module {

View File

@@ -9,7 +9,7 @@
import Cocoa
import Kit
public struct CPU_Load: value_t, Codable {
public struct CPU_Load: Codable {
var totalUsage: Double = 0
var usagePerCore: [Double] = []
var usageECores: Double? = nil
@@ -18,12 +18,6 @@ public struct CPU_Load: value_t, Codable {
var systemLoad: Double = 0
var userLoad: Double = 0
var idleLoad: Double = 0
public var widgetValue: Double {
get {
return self.totalUsage
}
}
}
public struct CPU_Limit: Codable {

View File

@@ -173,14 +173,7 @@ internal class Settings: NSStackView, Settings_v {
}
@objc func toggleUsagePerCore(_ 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.usagePerCoreState = state! == .on ? true : false
self.usagePerCoreState = controlState(sender)
Store.shared.set(key: "\(self.title)_usagePerCore", value: self.usagePerCoreState)
self.callback()
@@ -205,53 +198,25 @@ internal class Settings: NSStackView, Settings_v {
}
@objc func toggleMultithreading(_ 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.hyperthreadState = state! == .on ? true : false
self.hyperthreadState = controlState(sender)
Store.shared.set(key: "\(self.title)_hyperhreading", value: self.hyperthreadState)
self.callback()
}
@objc func toggleIPG(_ 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.IPGState = state! == .on ? true : false
self.IPGState = controlState(sender)
Store.shared.set(key: "\(self.title)_IPG", value: self.IPGState)
self.IPGCallback(self.IPGState)
}
@objc func toggleSplitValue(_ 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.splitValueState = state! == .on ? true : false
self.splitValueState = controlState(sender)
Store.shared.set(key: "\(self.title)_splitValue", value: self.splitValueState)
self.callback()
}
@objc func toggleClustersGroup(_ 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.clustersGroupState = state! == .on ? true : false
self.clustersGroupState = controlState(sender)
Store.shared.set(key: "\(self.title)_clustersGroup", value: self.clustersGroupState)
self.splitValueView?.isEnabled = !(self.usagePerCoreState || self.clustersGroupState)

View File

@@ -238,12 +238,6 @@ public class Disk: Module {
self.setReaders([self.capacityReader, self.activityReader, self.processReader])
}
public override func widgetDidSet(_ type: widget_t) {
if type == .speed && self.capacityReader?.interval != 1 {
self.settingsView.setUpdateInterval(value: 1)
}
}
private func capacityCallback(_ value: Disks) {
guard self.enabled else { return }
@@ -289,8 +283,16 @@ public class Disk: Module {
self.menuBar.widgets.filter{ $0.isActive }.forEach { (w: Widget) in
switch w.item {
case let widget as SpeedWidget: widget.setValue(upload: d.activity.write, download: d.activity.read)
case let widget as NetworkChart: widget.setValue(upload: Double(d.activity.write), download: Double(d.activity.read))
case let widget as SpeedWidget:
widget.setValue(upload: d.activity.write, download: d.activity.read)
if self.capacityReader?.interval != 1 {
self.settingsView.setUpdateInterval(value: 1)
}
case let widget as NetworkChart:
widget.setValue(upload: Double(d.activity.write), download: Double(d.activity.read))
if self.capacityReader?.interval != 1 {
self.settingsView.setUpdateInterval(value: 1)
}
default: break
}
}

View File

@@ -50,18 +50,12 @@ public struct GPU_Info: Codable {
}
}
public struct GPUs: value_t, Codable {
public struct GPUs: Codable {
public var list: [GPU_Info] = []
internal func active() -> [GPU_Info] {
return self.list.filter{ $0.state && $0.utilization != nil }.sorted{ $0.utilization ?? 0 > $1.utilization ?? 0 }
}
public var widgetValue: Double {
get {
return list.isEmpty ? 0 : (list[0].utilization ?? 0)
}
}
}
public class GPU: Module {

View File

@@ -66,7 +66,7 @@ public struct Bandwidth: Codable {
var download: Int64 = 0
}
public struct Network_Usage: value_t, Codable {
public struct Network_Usage: Codable {
var bandwidth: Bandwidth = Bandwidth()
var total: Bandwidth = Bandwidth()
@@ -90,8 +90,6 @@ public struct Network_Usage: value_t, Codable {
self.wifiDetails.reset()
}
public var widgetValue: Double = 0
}
public struct Network_Connectivity: Codable {

View File

@@ -12,7 +12,7 @@
import Cocoa
import Kit
public struct RAM_Usage: value_t, Codable {
public struct RAM_Usage: Codable {
var total: Double
var used: Double
var free: Double
@@ -29,12 +29,6 @@ public struct RAM_Usage: value_t, Codable {
var rawPressureLevel: UInt
var swap: Swap
public var widgetValue: Double {
get {
return self.usage
}
}
public var usage: Double {
get {
return Double((self.total - self.free) / self.total)

View File

@@ -112,7 +112,7 @@ public class Sensors: Module {
value = "\(f.percentage)%"
}
}
list.append(Stack_t(key: s.key, value: value, additional: s.name))
list.append(Stack_t(key: s.key, value: value))
}
}

View File

@@ -171,7 +171,7 @@ class ApplicationSettings: NSStackView {
NotificationCenter.default.removeObserver(self, name: .fanHelperState, object: nil)
}
public func viewWillAppear() {
internal func viewWillAppear() {
self.startAtLoginBtn?.state = LaunchAtLogin.isEnabled ? .on : .off
self.telemetryBtn?.state = telemetry.isEnabled ? .on : .off
@@ -240,7 +240,7 @@ class ApplicationSettings: NSStackView {
// MARK: - actions
@objc private func updateAction(_ sender: NSObject) {
@objc private func updateAction() {
updater.check(force: true, completion: { result, error in
if error != nil {
debug("error updater.check(): \(error!.localizedDescription)")
@@ -309,7 +309,7 @@ class ApplicationSettings: NSStackView {
NotificationCenter.default.post(name: .combinedModulesPopup, object: nil, userInfo: nil)
}
@objc private func importSettings(_ sender: NSObject) {
@objc private func importSettings() {
let panel = NSOpenPanel()
panel.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.modalPanelWindow)))
panel.begin { (result) in
@@ -320,7 +320,7 @@ class ApplicationSettings: NSStackView {
}
}
@objc private func exportSettings(_ sender: NSObject) {
@objc private func exportSettings() {
let panel = NSSavePanel()
panel.nameFieldStringValue = "Stats.plist"
panel.showsTagField = false
@@ -333,7 +333,7 @@ class ApplicationSettings: NSStackView {
}
}
@objc private func resetSettings(_ sender: NSObject) {
@objc private func resetSettings() {
let alert = NSAlert()
alert.messageText = localizedString("Reset settings")
alert.informativeText = localizedString("Reset settings text")
@@ -482,12 +482,10 @@ private class ModuleSelectorView: NSStackView {
}
}
internal class ModulePreview: NSStackView {
private let id: String
private class ModulePreview: NSStackView {
private let imageView: NSImageView
public init(id: String, icon: NSImage?) {
self.id = id
fileprivate init(id: String, icon: NSImage?) {
self.imageView = NSImageView(frame: NSRect(origin: .zero, size: NSSize(width: Constants.Widget.height, height: Constants.Widget.height)))
let size: CGSize = CGSize(width: Constants.Widget.height + (Constants.Widget.spacing * 2), height: Constants.Widget.height)

View File

@@ -12,7 +12,7 @@
import Cocoa
import Kit
class CombinedView: NSObject, NSGestureRecognizerDelegate {
internal class CombinedView: NSObject, NSGestureRecognizerDelegate {
private var menuBarItem: NSStatusItem? = nil
private var view: NSView = NSView(frame: NSRect(x: 0, y: 0, width: 0, height: Constants.Widget.height))
private var popup: PopupWindow? = nil
@@ -194,7 +194,8 @@ class CombinedView: NSObject, NSGestureRecognizerDelegate {
}
private class Popup: NSStackView, Popup_p {
public var sizeCallback: ((NSSize) -> Void)? = nil
fileprivate var sizeCallback: ((NSSize) -> Void)? = nil
let log = NextLog(writer: .file)
init() {
super.init(frame: NSRect(x: 0, y: 0, width: Constants.Popup.width, height: 0))
@@ -217,16 +218,18 @@ private class Popup: NSStackView, Popup_p {
NotificationCenter.default.removeObserver(self, name: .toggleOneView, object: nil)
}
public func settings() -> NSView? { return nil }
public func appear() {}
public func disappear() {}
fileprivate func settings() -> NSView? { return nil }
fileprivate func appear() {}
fileprivate func disappear() {}
@objc private func reinit() {
self.subviews.forEach({ $0.removeFromSuperview() })
let availableModules = modules.filter({ $0.enabled && $0.portal != nil })
debug("modules: \(availableModules.count)", log: self.log)
availableModules.forEach { (m: Module) in
if let p = m.portal {
debug("adding: \(m.name) portal", log: self.log)
self.addArrangedSubview(p)
}
}

View File

@@ -224,6 +224,7 @@ class Dashboard: NSStackView {
osField.alignment = .center
osField.font = NSFont.systemFont(ofSize: 12, weight: .regular)
osField.stringValue = "macOS \(SystemKit.shared.device.os?.name ?? localizedString("Unknown")) (\(SystemKit.shared.device.os?.version.getFullVersion() ?? ""))"
osField.toolTip = SystemKit.shared.device.os?.build ?? localizedString("Unknown")
osField.isSelectable = true
container.addRow(with: [deviceImageView])

View File

@@ -211,7 +211,7 @@ class SettingsWindow: NSWindow, NSWindowDelegate, NSToolbarDelegate {
}
}
public func setModules() {
internal func setModules() {
self.sidebarView.setModules(modules)
if !self.pauseState && modules.filter({ $0.enabled != false && $0.available != false && !$0.menuBar.widgets.filter({ $0.isActive }).isEmpty }).isEmpty {
self.setIsVisible(true)
@@ -229,7 +229,7 @@ class SettingsWindow: NSWindow, NSWindowDelegate, NSToolbarDelegate {
// MARK: - MainView
private class MainView: NSView {
public let container: NSStackView
fileprivate let container: NSStackView
override init(frame: NSRect) {
self.container = NSStackView(frame: NSRect(x: 0, y: 0, width: frame.width, height: frame.height))
@@ -251,7 +251,7 @@ private class MainView: NSView {
fatalError("init(coder:) has not been implemented")
}
public func setView(_ view: NSView) {
fileprivate func setView(_ view: NSView) {
self.container.subviews.forEach{ $0.removeFromSuperview() }
self.container.addArrangedSubview(view)
@@ -380,7 +380,7 @@ private class SidebarView: NSStackView {
fatalError("init(coder:) has not been implemented")
}
public func openMenu(_ title: String) {
fileprivate func openMenu(_ title: String) {
self.scrollView.stackView.subviews.forEach({ (m: NSView) in
if let menu = m as? MenuItem {
if menu.title == title {
@@ -392,7 +392,7 @@ private class SidebarView: NSStackView {
})
}
public func setModules(_ list: [Module]) {
fileprivate func setModules(_ list: [Module]) {
list.reversed().forEach { (m: Module) in
if !m.available { return }
let menu: NSView = MenuItem(icon: m.config.icon, title: m.config.name)
@@ -460,26 +460,7 @@ private class SidebarView: NSStackView {
return vc
}
private func supportButton(name: String, image: String, action: Selector) -> NSButton {
let button = NSButtonWithPadding()
button.frame = CGRect(x: 0, y: 0, width: 24, height: 24)
button.verticalPadding = 16
button.horizontalPadding = 16
button.title = name
button.toolTip = name
button.bezelStyle = .regularSquare
button.translatesAutoresizingMaskIntoConstraints = false
button.imageScaling = .scaleNone
button.image = Bundle(for: type(of: self)).image(forResource: image)!
button.isBordered = false
button.target = self
button.focusRingType = .none
button.action = action
return button
}
@objc private func reportBug(_ sender: Any) {
@objc private func reportBug() {
NSWorkspace.shared.open(URL(string: "https://github.com/exelban/stats/issues/new")!)
}
@@ -487,11 +468,11 @@ private class SidebarView: NSStackView {
self.supportPopover.show(relativeTo: sender.bounds, of: sender, preferredEdge: NSRectEdge.minY)
}
@objc private func closeApp(_ sender: Any) {
@objc private func closeApp(_ sender: NSButton) {
NSApp.terminate(sender)
}
@objc private func togglePause(_ sender: NSButton) {
@objc private func togglePause() {
self.pauseState = !self.pauseState
self.pauseButton?.toolTip = localizedString(self.pauseState ? "Resume the Stats" : "Pause the Stats")
self.pauseButton?.image = self.pauseState ? self.resumeIcon : self.pauseIcon
@@ -505,9 +486,9 @@ private class SidebarView: NSStackView {
}
private class MenuItem: NSView {
public let title: String
public var active: Bool = false
fileprivate let title: String
private var active: Bool = false
private var imageView: NSImageView? = nil
private var titleView: NSTextField? = nil
@@ -560,7 +541,7 @@ private class MenuItem: NSView {
self.activate()
}
public func activate() {
fileprivate func activate() {
guard !self.active else { return }
self.active = true
@@ -571,7 +552,7 @@ private class MenuItem: NSView {
self.titleView?.textColor = .white
}
public func reset() {
fileprivate func reset() {
self.layer?.backgroundColor = .clear
self.imageView?.contentTintColor = .labelColor
self.titleView?.textColor = .labelColor

View File

@@ -15,11 +15,11 @@ import Kit
private let setupSize: CGSize = CGSize(width: 600, height: 400)
internal class SetupWindow: NSWindow, NSWindowDelegate {
internal var finishHandler: () -> Void = {}
private let view: SetupContainer = SetupContainer()
private let vc: NSViewController = NSViewController(nibName: nil, bundle: nil)
public var finishHandler: () -> Void = {}
init() {
self.vc.view = self.view
@@ -44,12 +44,12 @@ internal class SetupWindow: NSWindow, NSWindowDelegate {
windowController.loadWindow()
}
public func show() {
internal func show() {
self.setIsVisible(true)
self.orderFrontRegardless()
}
public func hide() {
internal func hide() {
self.close()
}
@@ -496,10 +496,10 @@ private class SetupView_end: NSStackView {
}
}
public class SupportButtonView: NSButton {
public var callback: (() -> Void) = {}
internal class SupportButtonView: NSButton {
internal var callback: (() -> Void) = {}
public init(name: String, image: String, action: @escaping () -> Void) {
init(name: String, image: String, action: @escaping () -> Void) {
self.callback = action
super.init(frame: NSRect(x: 0, y: 0, width: 30, height: 30))
@@ -544,7 +544,7 @@ public class SupportButtonView: NSButton {
NSCursor.arrow.set()
}
@objc private func click(_ sender: NSControl) {
@objc private func click() {
self.callback()
}
}

View File

@@ -12,7 +12,7 @@
import Cocoa
import Kit
class UpdateWindow: NSWindow, NSWindowDelegate {
internal class UpdateWindow: NSWindow, NSWindowDelegate {
private let viewController: UpdateViewController = UpdateViewController()
init() {
@@ -39,7 +39,7 @@ class UpdateWindow: NSWindow, NSWindowDelegate {
windowController.loadWindow()
}
public func open(_ v: version_s, settingButton: Bool = false) {
internal func open(_ v: version_s, settingButton: Bool = false) {
if !self.isVisible || settingButton {
self.setIsVisible(true)
self.makeKeyAndOrderFront(nil)
@@ -68,7 +68,7 @@ private class UpdateViewController: NSViewController {
fatalError("init(coder:) has not been implemented")
}
public func open(_ v: version_s) {
internal func open(_ v: version_s) {
self.update.clear()
if v.newest {
@@ -99,7 +99,7 @@ private class UpdateView: NSView {
fatalError("init(coder:) has not been implemented")
}
public func newVersion(_ version: version_s) {
internal func newVersion(_ version: version_s) {
self.version = version
let view: NSStackView = NSStackView(frame: NSRect(
x: Constants.Settings.margin,
@@ -190,7 +190,7 @@ private class UpdateView: NSView {
self.addSubview(view)
}
public func noUpdates() {
internal func noUpdates() {
let view: NSView = NSView(frame: NSRect(x: 10, y: 10, width: self.frame.width - 20, height: self.frame.height - 20))
let title: NSTextField = TextView(frame: NSRect(x: 0, y: ((view.frame.height - 18)/2), width: view.frame.width, height: 34))
@@ -209,11 +209,11 @@ private class UpdateView: NSView {
self.addSubview(view)
}
public func clear() {
internal func clear() {
self.subviews.filter{ !($0 is NSVisualEffectView) }.forEach{ $0.removeFromSuperview() }
}
@objc private func download(_ sender: Any) {
@objc private func download() {
guard let urlString = self.version?.url, let url = URL(string: urlString) else {
return
}
@@ -273,17 +273,17 @@ private class UpdateView: NSView {
self.addSubview(view)
}
@objc private func close(_ sender: Any) {
@objc private func close() {
self.window?.close()
}
@objc private func changelog(_ sender: Any) {
@objc private func changelog() {
if let version = self.version {
NSWorkspace.shared.open(URL(string: "https://github.com/exelban/stats/releases/tag/\(version.latest)")!)
}
}
@objc private func install(_ sender: Any) {
@objc private func install() {
updater.install(path: self.path) { error in
if let error {
showAlert("Error update Stats", error, .critical)

View File

@@ -16,54 +16,54 @@ class RAM: XCTestCase {
func testProcessReader_parseProcess() throws {
var process = ProcessReader.parseProcess("3127 lldb-rpc-server 611M")
XCTAssertEqual(process.pid, 3127)
XCTAssertEqual(process.command, "lldb-rpc-server")
XCTAssertEqual(process.name, "lldb-rpc-server")
XCTAssertEqual(process.usage, 611 * Double(1024 * 1024))
process = ProcessReader.parseProcess("257 WindowServer 210M")
XCTAssertEqual(process.pid, 257)
XCTAssertEqual(process.command, "WindowServer")
XCTAssertEqual(process.name, "WindowServer")
XCTAssertEqual(process.usage, 210 * Double(1024 * 1024))
process = ProcessReader.parseProcess("7752 phpstorm 1819M")
XCTAssertEqual(process.pid, 7752)
XCTAssertEqual(process.command, "phpstorm")
XCTAssertEqual(process.name, "phpstorm")
XCTAssertEqual(process.usage, 1819 * Double(1024 * 1024))
process = ProcessReader.parseProcess("359 NotificationCent 62M")
XCTAssertEqual(process.pid, 359)
XCTAssertEqual(process.command, "NotificationCent")
XCTAssertEqual(process.name, "NotificationCent")
XCTAssertEqual(process.usage, 62 * Double(1024 * 1024))
process = ProcessReader.parseProcess("623 SafariCloudHisto 1608K")
XCTAssertEqual(process.pid, 623)
XCTAssertEqual(process.command, "SafariCloudHisto")
XCTAssertEqual(process.name, "SafariCloudHisto")
XCTAssertEqual(process.usage, (1608/1024) * Double(1024 * 1024))
process = ProcessReader.parseProcess("174 WindowServer 1442M+ ")
XCTAssertEqual(process.pid, 174)
XCTAssertEqual(process.command, "WindowServer")
XCTAssertEqual(process.name, "WindowServer")
XCTAssertEqual(process.usage, 1442 * Double(1024 * 1024))
process = ProcessReader.parseProcess("329 Finder 488M+ ")
XCTAssertEqual(process.pid, 329)
XCTAssertEqual(process.command, "Finder")
XCTAssertEqual(process.name, "Finder")
XCTAssertEqual(process.usage, 488 * Double(1024 * 1024))
process = ProcessReader.parseProcess("7163* AutoCAD LT 2023 11G ")
XCTAssertEqual(process.pid, 7163)
XCTAssertEqual(process.command, "AutoCAD LT 2023")
XCTAssertEqual(process.name, "AutoCAD LT 2023")
XCTAssertEqual(process.usage, 11 * Double(1024 * 1024 * 1024))
}
func testKernelTask() throws {
var process = ProcessReader.parseProcess("0 kernel_task 270M ")
XCTAssertEqual(process.pid, 0)
XCTAssertEqual(process.command, "kernel_task")
XCTAssertEqual(process.name, "kernel_task")
XCTAssertEqual(process.usage, 270 * Double(1024 * 1024))
process = ProcessReader.parseProcess("0 kernel_task 280M")
XCTAssertEqual(process.pid, 0)
XCTAssertEqual(process.command, "kernel_task")
XCTAssertEqual(process.name, "kernel_task")
XCTAssertEqual(process.usage, 280 * Double(1024 * 1024))
}
}