mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
BugFix: Multiple object creation
This commit is contained in:
parent
1a45d4e7f4
commit
f4bcb96906
8 changed files with 202 additions and 33 deletions
|
|
@ -10,16 +10,13 @@ import Cocoa
|
|||
import Foundation
|
||||
import Defaults
|
||||
|
||||
class SystemChangesObserver: ObservableObject {
|
||||
class SystemChangesObserver {
|
||||
private var oldVolume: Float
|
||||
private var oldMuted: Bool
|
||||
private var oldBrightness: Float = 0
|
||||
|
||||
private weak var coordinator: DynamicIslandViewCoordinator?
|
||||
|
||||
@Default(.enableSystemHUD) var enableSystemHUD
|
||||
@Default(.enableVolumeHUD) var enableVolumeHUD
|
||||
@Default(.enableBrightnessHUD) var enableBrightnessHUD
|
||||
private var timer: Timer?
|
||||
|
||||
init(coordinator: DynamicIslandViewCoordinator) {
|
||||
self.coordinator = coordinator
|
||||
|
|
@ -34,18 +31,18 @@ class SystemChangesObserver: ObservableObject {
|
|||
}
|
||||
|
||||
func startObserving() {
|
||||
guard enableSystemHUD else { return }
|
||||
guard Defaults[.enableSystemHUD] else { return }
|
||||
|
||||
createObservers()
|
||||
createTimerForContinuousChangesCheck(with: 0.2)
|
||||
}
|
||||
|
||||
private func createTimerForContinuousChangesCheck(with seconds: TimeInterval) {
|
||||
let timer = Timer(
|
||||
timer = Timer(
|
||||
timeInterval: seconds, target: self, selector: #selector(checkChanges), userInfo: nil,
|
||||
repeats: true)
|
||||
let mainLoop = RunLoop.main
|
||||
mainLoop.add(timer, forMode: .common)
|
||||
mainLoop.add(timer!, forMode: .common)
|
||||
}
|
||||
|
||||
private func createObservers() {
|
||||
|
|
@ -63,7 +60,7 @@ class SystemChangesObserver: ObservableObject {
|
|||
}
|
||||
|
||||
@objc func showVolumeHUD() {
|
||||
guard enableSystemHUD && enableVolumeHUD else { return }
|
||||
guard Defaults[.enableSystemHUD] && Defaults[.enableVolumeHUD] else { return }
|
||||
|
||||
if oldVolume == 0.0 || oldVolume == 1.0 {
|
||||
sendVolumeNotification(value: oldVolume)
|
||||
|
|
@ -72,7 +69,7 @@ class SystemChangesObserver: ObservableObject {
|
|||
}
|
||||
|
||||
@objc func showBrightnessHUD() {
|
||||
guard enableSystemHUD && enableBrightnessHUD else { return }
|
||||
guard Defaults[.enableSystemHUD] && Defaults[.enableBrightnessHUD] else { return }
|
||||
|
||||
if oldBrightness == 0.0 || oldBrightness == 1.0 {
|
||||
sendBrightnessNotification(value: oldBrightness)
|
||||
|
|
@ -81,7 +78,7 @@ class SystemChangesObserver: ObservableObject {
|
|||
}
|
||||
|
||||
@objc func checkChanges() {
|
||||
guard enableSystemHUD else { return }
|
||||
guard Defaults[.enableSystemHUD] else { return }
|
||||
|
||||
checkBrightnessChanges()
|
||||
checkVolumeChanges()
|
||||
|
|
@ -93,7 +90,7 @@ class SystemChangesObserver: ObservableObject {
|
|||
}
|
||||
|
||||
private func checkVolumeChanges() {
|
||||
guard enableVolumeHUD else { return }
|
||||
guard Defaults[.enableVolumeHUD] else { return }
|
||||
|
||||
let newVolume = SystemVolumeManager.getOutputVolume()
|
||||
let newMuted = SystemVolumeManager.isMuted()
|
||||
|
|
@ -110,7 +107,7 @@ class SystemChangesObserver: ObservableObject {
|
|||
}
|
||||
|
||||
private func checkBrightnessChanges() {
|
||||
guard enableBrightnessHUD else { return }
|
||||
guard Defaults[.enableBrightnessHUD] else { return }
|
||||
|
||||
if NSScreen.screens.count == 0 {
|
||||
return
|
||||
|
|
@ -148,6 +145,12 @@ class SystemChangesObserver: ObservableObject {
|
|||
}
|
||||
|
||||
deinit {
|
||||
stopObserving()
|
||||
}
|
||||
|
||||
func stopObserving() {
|
||||
timer?.invalidate()
|
||||
timer = nil
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
}
|
||||
|
|
@ -7,31 +7,38 @@
|
|||
|
||||
import Foundation
|
||||
import Defaults
|
||||
import Combine
|
||||
|
||||
class SystemHUDManager: ObservableObject {
|
||||
class SystemHUDManager {
|
||||
static let shared = SystemHUDManager()
|
||||
|
||||
private var changesObserver: SystemChangesObserver?
|
||||
private weak var coordinator: DynamicIslandViewCoordinator?
|
||||
|
||||
@Default(.enableSystemHUD) var enableSystemHUD {
|
||||
didSet {
|
||||
Task { @MainActor in
|
||||
if enableSystemHUD {
|
||||
await startSystemHUD()
|
||||
} else {
|
||||
await stopSystemHUD()
|
||||
}
|
||||
}
|
||||
}
|
||||
private init() {
|
||||
// Set up observer for settings changes
|
||||
setupSettingsObserver()
|
||||
}
|
||||
|
||||
private init() {}
|
||||
private func setupSettingsObserver() {
|
||||
// Use Defaults publisher instead of @Default property wrapper
|
||||
Defaults.publisher(.enableSystemHUD, options: []).sink { [weak self] change in
|
||||
Task { @MainActor in
|
||||
if change.newValue {
|
||||
await self?.startSystemHUD()
|
||||
} else {
|
||||
await self?.stopSystemHUD()
|
||||
}
|
||||
}
|
||||
}.store(in: &cancellables)
|
||||
}
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
func setup(coordinator: DynamicIslandViewCoordinator) {
|
||||
self.coordinator = coordinator
|
||||
|
||||
if enableSystemHUD {
|
||||
if Defaults[.enableSystemHUD] {
|
||||
Task { @MainActor in
|
||||
await startSystemHUD()
|
||||
}
|
||||
|
|
@ -56,6 +63,7 @@ class SystemHUDManager: ObservableObject {
|
|||
|
||||
@MainActor
|
||||
private func stopSystemHUD() async {
|
||||
changesObserver?.stopObserving()
|
||||
changesObserver = nil
|
||||
|
||||
// Re-enable system HUD
|
||||
|
|
@ -65,18 +73,36 @@ class SystemHUDManager: ObservableObject {
|
|||
}
|
||||
|
||||
private func disableSystemHUD() {
|
||||
print("🔇 Disabling system HUD (OSDUIHelper running: \(SystemOSDManager.isOSDUIHelperRunning()))")
|
||||
// Disable the system HUD using SystemOSDManager
|
||||
SystemOSDManager.disableSystemHUD()
|
||||
}
|
||||
|
||||
private func enableOriginalSystemHUD() {
|
||||
print("🔊 Re-enabling system HUD (OSDUIHelper running: \(SystemOSDManager.isOSDUIHelperRunning()))")
|
||||
// Re-enable the system HUD using SystemOSDManager
|
||||
SystemOSDManager.enableSystemHUD()
|
||||
|
||||
// Verify it's working after a short delay
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
|
||||
let isRunning = SystemOSDManager.isOSDUIHelperRunning()
|
||||
print("🔍 OSDUIHelper status after re-enable: \(isRunning ? "✅ Running" : "❌ Not running")")
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
print("🧹 SystemHUDManager deinitializing - ensuring system HUD is restored")
|
||||
cancellables.removeAll()
|
||||
Task { @MainActor in
|
||||
await stopSystemHUD()
|
||||
}
|
||||
// Also call the emergency restore as backup
|
||||
SystemHUDDebugger.forceRestartOSDUIHelper()
|
||||
}
|
||||
|
||||
/// Emergency restore function - call this if system HUD is not working
|
||||
public static func emergencyRestoreSystemHUD() {
|
||||
print("🚨 Emergency system HUD restore initiated")
|
||||
SystemHUDDebugger.forceRestartOSDUIHelper()
|
||||
}
|
||||
}
|
||||
|
|
@ -14,13 +14,41 @@ class SystemOSDManager {
|
|||
/// Re-enables the system HUD by restarting OSDUIHelper
|
||||
public static func enableSystemHUD() {
|
||||
do {
|
||||
let task = Process()
|
||||
task.executableURL = URL(fileURLWithPath: "/usr/bin/killall")
|
||||
task.arguments = ["-9", "OSDUIHelper"]
|
||||
try task.run()
|
||||
print("System HUD re-enabled")
|
||||
// First, stop any existing OSDUIHelper process
|
||||
let stopTask = Process()
|
||||
stopTask.executableURL = URL(fileURLWithPath: "/usr/bin/killall")
|
||||
stopTask.arguments = ["-9", "OSDUIHelper"]
|
||||
try stopTask.run()
|
||||
stopTask.waitUntilExit()
|
||||
|
||||
// Small delay to ensure process is fully stopped
|
||||
usleep(200000) // 200ms
|
||||
|
||||
// Then kickstart it again to ensure it's running properly
|
||||
let kickstart = Process()
|
||||
kickstart.executableURL = URL(fileURLWithPath: "/bin/launchctl")
|
||||
kickstart.arguments = ["kickstart", "gui/\(getuid())/com.apple.OSDUIHelper"]
|
||||
try kickstart.run()
|
||||
kickstart.waitUntilExit()
|
||||
|
||||
// Additional delay to ensure service is fully started
|
||||
usleep(300000) // 300ms
|
||||
|
||||
print("✅ System HUD re-enabled")
|
||||
} catch {
|
||||
NSLog("Error while trying to re-enable OSDUIHelper. \(error)")
|
||||
NSLog("❌ Error while trying to re-enable OSDUIHelper: \(error)")
|
||||
|
||||
// Fallback: Try to restart the service using launchctl load
|
||||
do {
|
||||
let fallbackTask = Process()
|
||||
fallbackTask.executableURL = URL(fileURLWithPath: "/bin/launchctl")
|
||||
fallbackTask.arguments = ["load", "-w", "/System/Library/LaunchAgents/com.apple.OSDUIHelper.plist"]
|
||||
try fallbackTask.run()
|
||||
fallbackTask.waitUntilExit()
|
||||
print("✅ System HUD re-enabled via fallback method")
|
||||
} catch {
|
||||
NSLog("❌ Fallback method also failed: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -39,9 +67,33 @@ class SystemOSDManager {
|
|||
task.executableURL = URL(fileURLWithPath: "/usr/bin/killall")
|
||||
task.arguments = ["-STOP", "OSDUIHelper"]
|
||||
try task.run()
|
||||
print("System HUD disabled")
|
||||
task.waitUntilExit()
|
||||
|
||||
print("✅ System HUD disabled")
|
||||
} catch {
|
||||
NSLog("Error while trying to hide OSDUIHelper. Please create an issue on GitHub. Error: \(error)")
|
||||
NSLog("❌ Error while trying to hide OSDUIHelper: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if OSDUIHelper is currently running
|
||||
public static func isOSDUIHelperRunning() -> Bool {
|
||||
let task = Process()
|
||||
task.executableURL = URL(fileURLWithPath: "/usr/bin/pgrep")
|
||||
task.arguments = ["OSDUIHelper"]
|
||||
|
||||
let pipe = Pipe()
|
||||
task.standardOutput = pipe
|
||||
|
||||
do {
|
||||
try task.run()
|
||||
task.waitUntilExit()
|
||||
|
||||
let data = pipe.fileHandleForReading.readDataToEndOfFile()
|
||||
let output = String(data: data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
|
||||
return task.terminationStatus == 0 && !output!.isEmpty
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue