mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
feat: added a button to uninstall the fans helper
This commit is contained in:
@@ -1127,6 +1127,12 @@ public class SMCHelper {
|
||||
|
||||
return helper
|
||||
}
|
||||
|
||||
public func uninstall() {
|
||||
guard let helper = self.helper(nil) else { return }
|
||||
helper.uninstall()
|
||||
NotificationCenter.default.post(name: .fanHelperState, object: nil, userInfo: ["state": false])
|
||||
}
|
||||
}
|
||||
|
||||
internal func grayscaleImage(_ image: NSImage) -> NSImage? {
|
||||
|
||||
@@ -752,9 +752,7 @@ internal class FanView: NSStackView {
|
||||
}
|
||||
|
||||
@objc private func changeHelperState(_ notification: Notification) {
|
||||
guard let state = notification.userInfo?["state"] as? Bool, self.helperView?.superview != nil else {
|
||||
return
|
||||
}
|
||||
guard let state = notification.userInfo?["state"] as? Bool else { return }
|
||||
self.setupControls(state)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,18 @@ class Helper: NSObject, NSXPCListenerDelegate, HelperProtocol {
|
||||
}
|
||||
|
||||
public func run() {
|
||||
let args = CommandLine.arguments.dropFirst()
|
||||
if !args.isEmpty && args.first == "uninstall" {
|
||||
NSLog("detected uninstall command")
|
||||
if let val = args.last, let pid: pid_t = Int32(val) {
|
||||
while kill(pid, 0) == 0 {
|
||||
usleep(50000)
|
||||
}
|
||||
}
|
||||
self.uninstallHelper()
|
||||
exit(0)
|
||||
}
|
||||
|
||||
self.listener.resume()
|
||||
while !self.shouldQuit {
|
||||
RunLoop.current.run(until: Date(timeIntervalSinceNow: self.shouldQuitCheckInterval))
|
||||
@@ -53,6 +65,34 @@ class Helper: NSObject, NSXPCListenerDelegate, HelperProtocol {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private func uninstallHelper() {
|
||||
let process = Process()
|
||||
process.launchPath = "/bin/launchctl"
|
||||
process.qualityOfService = QualityOfService.utility
|
||||
process.arguments = ["unload", "/Library/LaunchDaemons/eu.exelban.Stats.SMC.Helper.plist"]
|
||||
process.launch()
|
||||
process.waitUntilExit()
|
||||
|
||||
if process.terminationStatus != .zero {
|
||||
NSLog("termination code: \(process.terminationStatus)")
|
||||
}
|
||||
NSLog("unloaded from launchctl")
|
||||
|
||||
do {
|
||||
try FileManager.default.removeItem(at: URL(fileURLWithPath: "/Library/LaunchDaemons/eu.exelban.Stats.SMC.Helper.plist"))
|
||||
} catch let err {
|
||||
NSLog("plist deletion: \(err)")
|
||||
}
|
||||
NSLog("property list deleted")
|
||||
|
||||
do {
|
||||
try FileManager.default.removeItem(at: URL(fileURLWithPath: "/Library/PrivilegedHelperTools/eu.exelban.Stats.SMC.Helper"))
|
||||
} catch let err {
|
||||
NSLog("helper deletion: \(err)")
|
||||
}
|
||||
NSLog("smc helper deleted")
|
||||
}
|
||||
}
|
||||
|
||||
extension Helper {
|
||||
@@ -94,4 +134,13 @@ extension Helper {
|
||||
let data = pipe.fileHandleForReading.readDataToEndOfFile()
|
||||
return String(data: data, encoding: .utf8)!
|
||||
}
|
||||
|
||||
func uninstall() {
|
||||
let process = Process()
|
||||
process.launchPath = "/Library/PrivilegedHelperTools/eu.exelban.Stats.SMC.Helper"
|
||||
process.qualityOfService = QualityOfService.utility
|
||||
process.arguments = ["uninstall", String(getpid())]
|
||||
process.launch()
|
||||
exit(0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,4 +17,6 @@ import Foundation
|
||||
|
||||
func setFanMode(id: Int, mode: Int, completion: @escaping (String?) -> Void)
|
||||
func setFanSpeed(id: Int, value: Int, completion: @escaping (String?) -> Void)
|
||||
|
||||
func uninstall()
|
||||
}
|
||||
|
||||
@@ -14,9 +14,7 @@ import Kit
|
||||
|
||||
class ApplicationSettings: NSStackView {
|
||||
private var updateIntervalValue: String {
|
||||
get {
|
||||
return Store.shared.string(key: "update-interval", defaultValue: AppUpdateInterval.silent.rawValue)
|
||||
}
|
||||
Store.shared.string(key: "update-interval", defaultValue: AppUpdateInterval.silent.rawValue)
|
||||
}
|
||||
|
||||
private var temperatureUnitsValue: String {
|
||||
@@ -41,14 +39,11 @@ class ApplicationSettings: NSStackView {
|
||||
private var updateSelector: NSPopUpButton?
|
||||
private var startAtLoginBtn: NSButton?
|
||||
private var pauseButton: NSButton?
|
||||
private var uninstallHelperButton: NSButton?
|
||||
private var buttonsContainer: NSStackView?
|
||||
|
||||
init() {
|
||||
super.init(frame: NSRect(
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 540,
|
||||
height: 480
|
||||
))
|
||||
super.init(frame: NSRect(x: 0, y: 0, width: Constants.Settings.width, height: Constants.Settings.height))
|
||||
|
||||
self.orientation = .vertical
|
||||
self.distribution = .fill
|
||||
@@ -61,6 +56,7 @@ class ApplicationSettings: NSStackView {
|
||||
self.addArrangedSubview(self.buttonsView())
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(listenForPause), name: .pause, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(toggleUninstallHelperButton), name: .fanHelperState, object: nil)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
@@ -68,7 +64,8 @@ class ApplicationSettings: NSStackView {
|
||||
}
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
NotificationCenter.default.removeObserver(self, name: .pause, object: nil)
|
||||
NotificationCenter.default.removeObserver(self, name: .fanHelperState, object: nil)
|
||||
}
|
||||
|
||||
public func viewWillAppear() {
|
||||
@@ -191,7 +188,11 @@ class ApplicationSettings: NSStackView {
|
||||
|
||||
private func buttonsView() -> NSView {
|
||||
let view = NSStackView()
|
||||
view.orientation = .vertical
|
||||
view.alignment = .centerY
|
||||
view.distribution = .fill
|
||||
view.heightAnchor.constraint(equalToConstant: 60).isActive = true
|
||||
self.buttonsContainer = view
|
||||
|
||||
let reset: NSButton = NSButton()
|
||||
reset.title = localizedString("Reset settings")
|
||||
@@ -206,8 +207,18 @@ class ApplicationSettings: NSStackView {
|
||||
pause.action = #selector(self.togglePause)
|
||||
self.pauseButton = pause
|
||||
|
||||
let uninstall: NSButton = NSButton()
|
||||
uninstall.title = localizedString("Uninstall fan helper")
|
||||
uninstall.bezelStyle = .rounded
|
||||
uninstall.target = self
|
||||
uninstall.action = #selector(self.uninstallHelper)
|
||||
self.uninstallHelperButton = uninstall
|
||||
|
||||
view.addArrangedSubview(reset)
|
||||
view.addArrangedSubview(pause)
|
||||
if SMCHelper.shared.isInstalled {
|
||||
view.addArrangedSubview(uninstall)
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
@@ -322,4 +333,19 @@ class ApplicationSettings: NSStackView {
|
||||
@objc func listenForPause() {
|
||||
self.pauseButton?.title = localizedString(self.pauseState ? "Resume the Stats" : "Pause the Stats")
|
||||
}
|
||||
|
||||
@objc private func toggleUninstallHelperButton(_ notification: Notification) {
|
||||
guard let state = notification.userInfo?["state"] as? Bool, let v = self.uninstallHelperButton else {
|
||||
return
|
||||
}
|
||||
if state && v.superview == nil {
|
||||
self.buttonsContainer?.addArrangedSubview(v)
|
||||
} else if !state && v.superview != nil {
|
||||
v.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func uninstallHelper() {
|
||||
SMCHelper.shared.uninstall()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user