mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
feat: initialized ProcessesView that will be common for all popups
This commit is contained in:
@@ -8,7 +8,6 @@
|
||||
//
|
||||
// Copyright © 2020 Serhiy Mytrovtsiy. All rights reserved.
|
||||
//
|
||||
// swiftlint:disable file_length
|
||||
|
||||
import Cocoa
|
||||
import ServiceManagement
|
||||
@@ -581,24 +580,21 @@ public func removeNotification(_ id: String) {
|
||||
center.removeDeliveredNotifications(withIdentifiers: [id])
|
||||
}
|
||||
|
||||
public struct TopProcess: Codable {
|
||||
public struct TopProcess: Codable, Process_p {
|
||||
public var pid: Int
|
||||
public var command: String
|
||||
public var name: String?
|
||||
public var name: String
|
||||
public var usage: Double
|
||||
|
||||
public var icon: NSImage? {
|
||||
public var icon: NSImage {
|
||||
get {
|
||||
if let app = NSRunningApplication(processIdentifier: pid_t(self.pid) ) {
|
||||
return app.icon
|
||||
if let app = NSRunningApplication(processIdentifier: pid_t(self.pid)), let icon = app.icon {
|
||||
return icon
|
||||
}
|
||||
return Constants.defaultProcessIcon
|
||||
}
|
||||
}
|
||||
|
||||
public init(pid: Int, command: String, name: String?, usage: Double) {
|
||||
public init(pid: Int, name: String, usage: Double) {
|
||||
self.pid = pid
|
||||
self.command = command
|
||||
self.name = name
|
||||
self.usage = usage
|
||||
}
|
||||
@@ -781,142 +777,6 @@ public func sysctlByName(_ name: String) -> Int64 {
|
||||
return num
|
||||
}
|
||||
|
||||
public class ProcessView: NSStackView {
|
||||
private var pid: Int? = nil
|
||||
private var lock: Bool = false
|
||||
|
||||
private var imageView: NSImageView = NSImageView()
|
||||
private var killView: NSButton = NSButton()
|
||||
private var labelView: LabelField = {
|
||||
let view = LabelField()
|
||||
view.cell?.truncatesLastVisibleLine = true
|
||||
return view
|
||||
}()
|
||||
private var valueView: ValueField = ValueField()
|
||||
|
||||
public init(size: CGSize = CGSize(width: 264, height: 22), valueSize: CGFloat = 55) {
|
||||
var rect = NSRect(x: 5, y: 5, width: 12, height: 12)
|
||||
if size.height != 22 {
|
||||
rect = NSRect(x: 3, y: 3, width: 12, height: 12)
|
||||
}
|
||||
self.imageView = NSImageView(frame: rect)
|
||||
self.killView = NSButton(frame: rect)
|
||||
|
||||
super.init(frame: NSRect(x: 0, y: 0, width: size.width, height: size.height))
|
||||
|
||||
self.wantsLayer = true
|
||||
self.orientation = .horizontal
|
||||
self.distribution = .fillProportionally
|
||||
self.spacing = 0
|
||||
self.layer?.cornerRadius = 3
|
||||
|
||||
let imageBox: NSView = {
|
||||
let view = NSView()
|
||||
|
||||
self.killView.bezelStyle = .regularSquare
|
||||
self.killView.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.killView.imageScaling = .scaleNone
|
||||
self.killView.image = Bundle(for: type(of: self)).image(forResource: "cancel")!
|
||||
self.killView.contentTintColor = .lightGray
|
||||
self.killView.isBordered = false
|
||||
self.killView.action = #selector(self.kill)
|
||||
self.killView.target = self
|
||||
self.killView.toolTip = localizedString("Kill process")
|
||||
self.killView.focusRingType = .none
|
||||
self.killView.isHidden = true
|
||||
|
||||
view.addSubview(self.imageView)
|
||||
view.addSubview(self.killView)
|
||||
|
||||
return view
|
||||
}()
|
||||
|
||||
self.addArrangedSubview(imageBox)
|
||||
self.addArrangedSubview(self.labelView)
|
||||
self.addArrangedSubview(self.valueView)
|
||||
|
||||
self.addTrackingArea(NSTrackingArea(
|
||||
rect: NSRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height),
|
||||
options: [NSTrackingArea.Options.activeAlways, NSTrackingArea.Options.mouseEnteredAndExited, NSTrackingArea.Options.activeInActiveApp],
|
||||
owner: self,
|
||||
userInfo: nil
|
||||
))
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
imageBox.widthAnchor.constraint(equalToConstant: self.bounds.height),
|
||||
imageBox.heightAnchor.constraint(equalToConstant: self.bounds.height),
|
||||
self.labelView.heightAnchor.constraint(equalToConstant: 16),
|
||||
self.valueView.widthAnchor.constraint(equalToConstant: valueSize),
|
||||
self.widthAnchor.constraint(equalToConstant: self.bounds.width),
|
||||
self.heightAnchor.constraint(equalToConstant: self.bounds.height)
|
||||
])
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
public override func mouseEntered(with: NSEvent) {
|
||||
if self.lock {
|
||||
self.imageView.isHidden = true
|
||||
self.killView.isHidden = false
|
||||
return
|
||||
}
|
||||
self.layer?.backgroundColor = .init(gray: 0.01, alpha: 0.05)
|
||||
}
|
||||
|
||||
public override func mouseExited(with: NSEvent) {
|
||||
if self.lock {
|
||||
self.imageView.isHidden = false
|
||||
self.killView.isHidden = true
|
||||
return
|
||||
}
|
||||
self.layer?.backgroundColor = .none
|
||||
}
|
||||
|
||||
public override func mouseDown(with: NSEvent) {
|
||||
self.setLock(!self.lock)
|
||||
}
|
||||
|
||||
public func set(_ process: TopProcess, _ value: String) {
|
||||
if self.lock && process.pid != self.pid { return }
|
||||
|
||||
self.labelView.stringValue = process.name != nil ? process.name! : process.command
|
||||
self.valueView.stringValue = value
|
||||
self.imageView.image = process.icon
|
||||
self.pid = process.pid
|
||||
self.toolTip = "pid: \(process.pid)"
|
||||
}
|
||||
|
||||
public func clear() {
|
||||
self.labelView.stringValue = ""
|
||||
self.valueView.stringValue = ""
|
||||
self.imageView.image = nil
|
||||
self.pid = nil
|
||||
self.setLock(false)
|
||||
self.toolTip = ""
|
||||
}
|
||||
|
||||
public func setLock(_ state: Bool) {
|
||||
self.lock = state
|
||||
if self.lock {
|
||||
self.imageView.isHidden = true
|
||||
self.killView.isHidden = false
|
||||
self.layer?.backgroundColor = .init(gray: 0.01, alpha: 0.1)
|
||||
} else {
|
||||
self.imageView.isHidden = false
|
||||
self.killView.isHidden = true
|
||||
self.layer?.backgroundColor = .none
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func kill() {
|
||||
if let pid = self.pid {
|
||||
asyncShell("kill \(pid)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class CAText: CATextLayer {
|
||||
public init(fontSize: CGFloat = 12, weight: NSFont.Weight = .regular) {
|
||||
super.init()
|
||||
|
||||
281
Kit/process.swift
Normal file
281
Kit/process.swift
Normal file
@@ -0,0 +1,281 @@
|
||||
//
|
||||
// process.swift
|
||||
// Kit
|
||||
//
|
||||
// Created by Serhiy Mytrovtsiy on 05/01/2024
|
||||
// Using Swift 5.0
|
||||
// Running on macOS 14.3
|
||||
//
|
||||
// Copyright © 2024 Serhiy Mytrovtsiy. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
public protocol Process_p {
|
||||
var pid: Int { get }
|
||||
var name: String { get }
|
||||
var icon: NSImage { get }
|
||||
}
|
||||
|
||||
public typealias ProcessHeader = (title: String, color: NSColor?)
|
||||
|
||||
public class ProcessesView: NSStackView {
|
||||
public var count: Int {
|
||||
self.list.count
|
||||
}
|
||||
private var list: [ProcessView] = []
|
||||
private var colorViews: [ColorView] = []
|
||||
|
||||
public init(frame: NSRect, values: [ProcessHeader], n: Int = 0) {
|
||||
super.init(frame: frame)
|
||||
|
||||
self.orientation = .vertical
|
||||
self.spacing = 0
|
||||
|
||||
let header = self.generateHeaderView(values)
|
||||
self.addArrangedSubview(header)
|
||||
|
||||
for _ in 0..<n {
|
||||
let view = ProcessView(n: values.count)
|
||||
self.addArrangedSubview(view)
|
||||
self.list.append(view)
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
private func generateHeaderView(_ values: [ProcessHeader]) -> NSView {
|
||||
let view = NSStackView()
|
||||
view.widthAnchor.constraint(equalToConstant: self.bounds.width).isActive = true
|
||||
view.heightAnchor.constraint(equalToConstant: ProcessView.height).isActive = true
|
||||
view.orientation = .horizontal
|
||||
view.distribution = .fillProportionally
|
||||
view.spacing = 0
|
||||
|
||||
let iconView: NSImageView = NSImageView()
|
||||
iconView.widthAnchor.constraint(equalToConstant: ProcessView.height).isActive = true
|
||||
iconView.heightAnchor.constraint(equalToConstant: ProcessView.height).isActive = true
|
||||
view.addArrangedSubview(iconView)
|
||||
|
||||
let titleField = LabelField()
|
||||
titleField.cell?.truncatesLastVisibleLine = true
|
||||
titleField.toolTip = "Process"
|
||||
titleField.stringValue = "Process"
|
||||
titleField.textColor = .tertiaryLabelColor
|
||||
titleField.font = NSFont.systemFont(ofSize: 12, weight: .medium)
|
||||
view.addArrangedSubview(titleField)
|
||||
|
||||
if values.count == 1, let v = values.first {
|
||||
let field = LabelField()
|
||||
field.cell?.truncatesLastVisibleLine = true
|
||||
field.toolTip = v.title
|
||||
field.stringValue = v.title
|
||||
field.alignment = .right
|
||||
field.textColor = .tertiaryLabelColor
|
||||
field.font = NSFont.systemFont(ofSize: 12, weight: .medium)
|
||||
view.addArrangedSubview(field)
|
||||
} else {
|
||||
for v in values {
|
||||
if let color = v.color {
|
||||
let container: NSView = NSView()
|
||||
container.widthAnchor.constraint(equalToConstant: 60).isActive = true
|
||||
container.heightAnchor.constraint(equalToConstant: ProcessView.height).isActive = true
|
||||
let colorBlock: ColorView = ColorView(frame: NSRect(x: 48, y: 5, width: 12, height: 12), color: color, state: true, radius: 4)
|
||||
colorBlock.toolTip = v.title
|
||||
colorBlock.widthAnchor.constraint(equalToConstant: 12).isActive = true
|
||||
colorBlock.heightAnchor.constraint(equalToConstant: 12).isActive = true
|
||||
self.colorViews.append(colorBlock)
|
||||
container.addSubview(colorBlock)
|
||||
view.addArrangedSubview(container)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
public func setLock(_ newValue: Bool) {
|
||||
self.list.forEach{ $0.setLock(newValue) }
|
||||
}
|
||||
|
||||
public func clear(_ symbol: String = "") {
|
||||
self.list.forEach{ $0.clear(symbol) }
|
||||
}
|
||||
|
||||
public func set(_ idx: Int, _ process: Process_p, _ values: [String]) {
|
||||
if self.list.indices.contains(idx) {
|
||||
self.list[idx].set(process, values)
|
||||
}
|
||||
}
|
||||
|
||||
public func setColor(_ idx: Int, _ newColor: NSColor) {
|
||||
if self.colorViews.indices.contains(idx) {
|
||||
self.colorViews[idx].setColor(newColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ProcessView: NSStackView {
|
||||
static let height: CGFloat = 22
|
||||
|
||||
private var pid: Int? = nil
|
||||
private var lock: Bool = false
|
||||
|
||||
private var imageView: NSImageView = NSImageView()
|
||||
private var killView: NSButton = NSButton()
|
||||
private var labelView: LabelField = {
|
||||
let view = LabelField()
|
||||
view.cell?.truncatesLastVisibleLine = true
|
||||
return view
|
||||
}()
|
||||
private var valueViews: [ValueField] = []
|
||||
|
||||
public init(size: CGSize = CGSize(width: 264, height: 22), n: Int = 1) {
|
||||
var rect = NSRect(x: 5, y: 5, width: 12, height: 12)
|
||||
if size.height != 22 {
|
||||
rect = NSRect(x: 3, y: 3, width: 12, height: 12)
|
||||
}
|
||||
self.imageView = NSImageView(frame: rect)
|
||||
self.killView = NSButton(frame: rect)
|
||||
|
||||
super.init(frame: NSRect(x: 0, y: 0, width: size.width, height: size.height))
|
||||
|
||||
self.wantsLayer = true
|
||||
self.orientation = .horizontal
|
||||
self.distribution = .fillProportionally
|
||||
self.spacing = 0
|
||||
self.layer?.cornerRadius = 3
|
||||
|
||||
let imageBox: NSView = {
|
||||
let view = NSView()
|
||||
|
||||
self.killView.bezelStyle = .regularSquare
|
||||
self.killView.translatesAutoresizingMaskIntoConstraints = false
|
||||
self.killView.imageScaling = .scaleNone
|
||||
self.killView.image = Bundle(for: type(of: self)).image(forResource: "cancel")!
|
||||
self.killView.contentTintColor = .lightGray
|
||||
self.killView.isBordered = false
|
||||
self.killView.action = #selector(self.kill)
|
||||
self.killView.target = self
|
||||
self.killView.toolTip = localizedString("Kill process")
|
||||
self.killView.focusRingType = .none
|
||||
self.killView.isHidden = true
|
||||
|
||||
view.addSubview(self.imageView)
|
||||
view.addSubview(self.killView)
|
||||
|
||||
return view
|
||||
}()
|
||||
|
||||
self.addArrangedSubview(imageBox)
|
||||
self.addArrangedSubview(self.labelView)
|
||||
self.valuesViews(n).forEach{ self.addArrangedSubview($0) }
|
||||
|
||||
self.addTrackingArea(NSTrackingArea(
|
||||
rect: NSRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height),
|
||||
options: [NSTrackingArea.Options.activeAlways, NSTrackingArea.Options.mouseEnteredAndExited, NSTrackingArea.Options.activeInActiveApp],
|
||||
owner: self,
|
||||
userInfo: nil
|
||||
))
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
imageBox.widthAnchor.constraint(equalToConstant: self.bounds.height),
|
||||
imageBox.heightAnchor.constraint(equalToConstant: self.bounds.height),
|
||||
self.labelView.heightAnchor.constraint(equalToConstant: 16),
|
||||
self.widthAnchor.constraint(equalToConstant: self.bounds.width),
|
||||
self.heightAnchor.constraint(equalToConstant: self.bounds.height)
|
||||
])
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
private func valuesViews(_ n: Int) -> [NSView] {
|
||||
var list: [ValueField] = []
|
||||
|
||||
for _ in 0..<n {
|
||||
let view: ValueField = ValueField()
|
||||
view.widthAnchor.constraint(equalToConstant: 60).isActive = true
|
||||
if n != 1 {
|
||||
view.font = NSFont.systemFont(ofSize: 10, weight: .regular)
|
||||
}
|
||||
list.append(view)
|
||||
}
|
||||
|
||||
self.valueViews = list
|
||||
return list
|
||||
}
|
||||
|
||||
public override func mouseEntered(with: NSEvent) {
|
||||
if self.lock {
|
||||
self.imageView.isHidden = true
|
||||
self.killView.isHidden = false
|
||||
return
|
||||
}
|
||||
self.layer?.backgroundColor = .init(gray: 0.01, alpha: 0.05)
|
||||
}
|
||||
|
||||
public override func mouseExited(with: NSEvent) {
|
||||
if self.lock {
|
||||
self.imageView.isHidden = false
|
||||
self.killView.isHidden = true
|
||||
return
|
||||
}
|
||||
self.layer?.backgroundColor = .none
|
||||
}
|
||||
|
||||
public override func mouseDown(with: NSEvent) {
|
||||
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]) {
|
||||
if self.lock && process.pid != self.pid { return }
|
||||
|
||||
self.labelView.stringValue = process.name
|
||||
values.enumerated().forEach({ self.valueViews[$0.offset].stringValue = $0.element })
|
||||
self.imageView.image = process.icon
|
||||
self.pid = process.pid
|
||||
self.toolTip = "pid: \(process.pid)"
|
||||
}
|
||||
|
||||
public func clear(_ symbol: String = "") {
|
||||
self.labelView.stringValue = symbol
|
||||
self.valueViews.forEach({ $0.stringValue = symbol })
|
||||
self.imageView.image = nil
|
||||
self.pid = nil
|
||||
self.setLock(false)
|
||||
self.toolTip = symbol
|
||||
}
|
||||
|
||||
public func setLock(_ state: Bool) {
|
||||
self.lock = state
|
||||
if self.lock {
|
||||
self.imageView.isHidden = true
|
||||
self.killView.isHidden = false
|
||||
self.layer?.backgroundColor = .init(gray: 0.01, alpha: 0.1)
|
||||
} else {
|
||||
self.imageView.isHidden = false
|
||||
self.killView.isHidden = true
|
||||
self.layer?.backgroundColor = .none
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func kill() {
|
||||
if let pid = self.pid {
|
||||
asyncShell("kill \(pid)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,12 +199,12 @@ public class ProcessReader: Reader<[TopProcess]> {
|
||||
return
|
||||
}
|
||||
|
||||
var name: String? = nil
|
||||
if let app = NSRunningApplication(processIdentifier: pid_t(pid) ) {
|
||||
name = app.localizedName ?? nil
|
||||
var name: String = command
|
||||
if let app = NSRunningApplication(processIdentifier: pid_t(pid)), let n = app.localizedName {
|
||||
name = n
|
||||
}
|
||||
|
||||
processes.append(TopProcess(pid: pid, command: command, name: name, usage: usage))
|
||||
processes.append(TopProcess(pid: pid, name: name, usage: usage))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -230,12 +230,12 @@ public class ProcessReader: Reader<[TopProcess]> {
|
||||
let pid = Int(pidFind.cropped) ?? 0
|
||||
let usage = Double(usageFind.cropped.replacingOccurrences(of: ",", with: ".")) ?? 0
|
||||
|
||||
var name: String? = nil
|
||||
if let app = NSRunningApplication(processIdentifier: pid_t(pid) ) {
|
||||
name = app.localizedName ?? nil
|
||||
var name: String = command
|
||||
if let app = NSRunningApplication(processIdentifier: pid_t(pid)), let n = app.localizedName {
|
||||
name = n
|
||||
}
|
||||
|
||||
processes.append(TopProcess(pid: pid, command: command, name: name, usage: usage))
|
||||
processes.append(TopProcess(pid: pid, name: name, usage: usage))
|
||||
}
|
||||
|
||||
if index == self.numberOfProcesses { stop = true }
|
||||
|
||||
@@ -158,15 +158,15 @@ public class Disks: Codable {
|
||||
}
|
||||
}
|
||||
|
||||
public struct Disk_process: IOProcess_p, Codable {
|
||||
private var base: DataSizeBase {
|
||||
public struct Disk_process: Process_p, Codable {
|
||||
public var base: DataSizeBase {
|
||||
DataSizeBase(rawValue: Store.shared.string(key: "\(Disk.name)_base", defaultValue: "byte")) ?? .byte
|
||||
}
|
||||
|
||||
public var pid: Int32
|
||||
public var pid: Int
|
||||
public var name: String
|
||||
public var icon: NSImage {
|
||||
if let app = NSRunningApplication(processIdentifier: self.pid) {
|
||||
if let app = NSRunningApplication(processIdentifier: pid_t(self.pid)) {
|
||||
return app.icon ?? Constants.defaultProcessIcon
|
||||
}
|
||||
return Constants.defaultProcessIcon
|
||||
@@ -182,13 +182,13 @@ public struct Disk_process: IOProcess_p, Codable {
|
||||
Units(bytes: Int64(self.write)).getReadableSpeed(base: self.base)
|
||||
}
|
||||
|
||||
init(pid: Int32, name: String, read: Int, write: Int) {
|
||||
init(pid: Int, name: String, read: Int, write: Int) {
|
||||
self.pid = pid
|
||||
self.name = name
|
||||
self.read = read
|
||||
self.write = write
|
||||
|
||||
if let app = NSRunningApplication(processIdentifier: pid) {
|
||||
if let app = NSRunningApplication(processIdentifier: pid_t(pid)) {
|
||||
if let name = app.localizedName {
|
||||
self.name = name
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ public class ProcessReader: Reader<[Disk_process]> {
|
||||
let read = bytesRead - v.read
|
||||
let write = bytesWritten - v.write
|
||||
if read != 0 || write != 0 {
|
||||
processes.append(Disk_process(pid: pid, name: name, read: read, write: write))
|
||||
processes.append(Disk_process(pid: Int(pid), name: name, read: read, write: write))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,20 +99,28 @@ public struct Network_Connectivity: Codable {
|
||||
var latency: Double = 0
|
||||
}
|
||||
|
||||
public struct Network_Process: Codable {
|
||||
var time: Date = Date()
|
||||
var name: String = ""
|
||||
var pid: String = ""
|
||||
var download: Int = 0
|
||||
var upload: Int = 0
|
||||
var icon: NSImage {
|
||||
public struct Network_Process: Codable, Process_p {
|
||||
public var pid: Int
|
||||
public var name: String
|
||||
public var time: Date
|
||||
public var download: Int
|
||||
public var upload: Int
|
||||
public var icon: NSImage {
|
||||
get {
|
||||
if let pid = pid_t(self.pid), let app = NSRunningApplication(processIdentifier: pid) {
|
||||
return app.icon ?? Constants.defaultProcessIcon
|
||||
if let app = NSRunningApplication(processIdentifier: pid_t(self.pid)), let icon = app.icon {
|
||||
return icon
|
||||
}
|
||||
return Constants.defaultProcessIcon
|
||||
}
|
||||
}
|
||||
|
||||
public init(pid: Int = 0, name: String = "", time: Date = Date(), download: Int = 0, upload: Int = 0) {
|
||||
self.pid = pid
|
||||
self.name = name
|
||||
self.time = time
|
||||
self.download = download
|
||||
self.upload = upload
|
||||
}
|
||||
}
|
||||
|
||||
public class Network: Module {
|
||||
|
||||
@@ -500,16 +500,16 @@ public class ProcessReader: Reader<[Network_Process]> {
|
||||
|
||||
let nameArray = parsedLine[0].split(separator: ".")
|
||||
if let pid = nameArray.last {
|
||||
process.pid = String(pid)
|
||||
process.pid = Int(pid) ?? 0
|
||||
}
|
||||
if let app = NSRunningApplication(processIdentifier: pid_t(process.pid) ?? 0) {
|
||||
if let app = NSRunningApplication(processIdentifier: pid_t(process.pid) ) {
|
||||
process.name = app.localizedName ?? nameArray.dropLast().joined(separator: ".")
|
||||
} else {
|
||||
process.name = nameArray.dropLast().joined(separator: ".")
|
||||
}
|
||||
|
||||
if process.name == "" {
|
||||
process.name = process.pid
|
||||
process.name = "\(process.pid)"
|
||||
}
|
||||
|
||||
if let download = Int(parsedLine[1]) {
|
||||
@@ -543,7 +543,7 @@ public class ProcessReader: Reader<[Network_Process]> {
|
||||
upload = 0
|
||||
}
|
||||
|
||||
processes.append(Network_Process(time: time, name: p.name, pid: p.pid, download: download, upload: upload))
|
||||
processes.append(Network_Process(pid: p.pid, name: p.name, time: time, download: download, upload: upload))
|
||||
}
|
||||
}
|
||||
self.previous = list
|
||||
|
||||
@@ -189,10 +189,10 @@ public class ProcessReader: Reader<[TopProcess]> {
|
||||
}
|
||||
|
||||
var name: String = command
|
||||
if let app = NSRunningApplication(processIdentifier: pid_t(pid) ) {
|
||||
name = app.localizedName ?? command
|
||||
if let app = NSRunningApplication(processIdentifier: pid_t(pid)), let n = app.localizedName {
|
||||
name = n
|
||||
}
|
||||
|
||||
return TopProcess(pid: pid, command: command, name: name, usage: usage * Double(1024 * 1024))
|
||||
return TopProcess(pid: pid, name: name, usage: usage * Double(1024 * 1024))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
5C23BC0C29A10BE000DBA990 /* portal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C23BC0B29A10BE000DBA990 /* portal.swift */; };
|
||||
5C23BC1029A3B5AE00DBA990 /* portal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C23BC0F29A3B5AE00DBA990 /* portal.swift */; };
|
||||
5C5647F82A3F6B100098FFE9 /* Telemetry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C5647F72A3F6B100098FFE9 /* Telemetry.swift */; };
|
||||
5C621D822B4770D6004ED7AF /* process.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C621D812B4770D6004ED7AF /* process.swift */; };
|
||||
5C8E001029269C7F0027C75A /* protocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CFE493829265055000F2856 /* protocol.swift */; };
|
||||
5CD342F42B2F2FB700225631 /* notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CD342F32B2F2FB700225631 /* notifications.swift */; };
|
||||
5CF2210D2B1E7EAF006C583F /* notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CF2210C2B1E7EAF006C583F /* notifications.swift */; };
|
||||
@@ -402,6 +403,7 @@
|
||||
5C23BC0B29A10BE000DBA990 /* portal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = portal.swift; sourceTree = "<group>"; };
|
||||
5C23BC0F29A3B5AE00DBA990 /* portal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = portal.swift; sourceTree = "<group>"; };
|
||||
5C5647F72A3F6B100098FFE9 /* Telemetry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Telemetry.swift; sourceTree = "<group>"; };
|
||||
5C621D812B4770D6004ED7AF /* process.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = process.swift; sourceTree = "<group>"; };
|
||||
5C9F90A02A76B30500D41748 /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
5CD342F32B2F2FB700225631 /* notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = notifications.swift; sourceTree = "<group>"; };
|
||||
5CF2210C2B1E7EAF006C583F /* notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = notifications.swift; sourceTree = "<group>"; };
|
||||
@@ -788,6 +790,7 @@
|
||||
9A28481A2666AB3500EC1F6D /* extensions.swift */,
|
||||
9A28481D2666AB3600EC1F6D /* helpers.swift */,
|
||||
9A28481C2666AB3500EC1F6D /* types.swift */,
|
||||
5C621D812B4770D6004ED7AF /* process.swift */,
|
||||
);
|
||||
path = Kit;
|
||||
sourceTree = "<group>";
|
||||
@@ -1746,6 +1749,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
5C8E001029269C7F0027C75A /* protocol.swift in Sources */,
|
||||
5C621D822B4770D6004ED7AF /* process.swift in Sources */,
|
||||
9AD7F866266F759200E5F863 /* smc.swift in Sources */,
|
||||
9A2847612666AA2700EC1F6D /* PieChart.swift in Sources */,
|
||||
9A2847672666AA2700EC1F6D /* BarChart.swift in Sources */,
|
||||
|
||||
Reference in New Issue
Block a user