potential crash fix

This commit is contained in:
Peter Steinberger 2025-06-19 10:50:46 +02:00
parent 812e0615cc
commit 8c48d8db52

View file

@ -9,7 +9,11 @@ import OSLog
/// is set to hide the dock icon. /// is set to hide the dock icon.
@MainActor @MainActor
final class DockIconManager: NSObject { final class DockIconManager: NSObject {
static let shared = DockIconManager() private static let _shared = DockIconManager()
static var shared: DockIconManager {
return _shared
}
private var windowsObservation: NSKeyValueObservation? private var windowsObservation: NSKeyValueObservation?
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "VibeTunnel", category: "DockIconManager") private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "VibeTunnel", category: "DockIconManager")
@ -17,12 +21,16 @@ final class DockIconManager: NSObject {
private override init() { private override init() {
super.init() super.init()
setupObservers() setupObservers()
// Initial update // Initial update after a small delay to ensure app state is ready
updateDockVisibility() Task { @MainActor in
try? await Task.sleep(for: .milliseconds(100))
self.updateDockVisibility()
}
} }
deinit { deinit {
windowsObservation?.invalidate() windowsObservation?.invalidate()
NotificationCenter.default.removeObserver(self)
} }
// MARK: - Public Methods // MARK: - Public Methods
@ -30,6 +38,12 @@ final class DockIconManager: NSObject {
/// Update dock visibility based on current state. /// Update dock visibility based on current state.
/// Call this when user preferences change or when you need to ensure proper state. /// Call this when user preferences change or when you need to ensure proper state.
func updateDockVisibility() { func updateDockVisibility() {
// Ensure NSApp is available before proceeding
guard NSApp != nil else {
logger.warning("NSApp not available yet, skipping dock visibility update")
return
}
let userWantsDockHidden = !UserDefaults.standard.bool(forKey: "showInDock") let userWantsDockHidden = !UserDefaults.standard.bool(forKey: "showInDock")
// Count visible windows (excluding panels and hidden windows) // Count visible windows (excluding panels and hidden windows)
@ -68,8 +82,19 @@ final class DockIconManager: NSObject {
// MARK: - Private Methods // MARK: - Private Methods
private func setupObservers() { private func setupObservers() {
// Ensure NSApp is available before setting up observers
guard NSApp != nil else {
logger.warning("NSApp not available, delaying observer setup")
Task { @MainActor in
try? await Task.sleep(for: .milliseconds(200))
self.setupObservers()
}
return
}
// Observe changes to NSApp.windows using KVO // Observe changes to NSApp.windows using KVO
windowsObservation = NSApp.observe(\.windows, options: [.initial, .new]) { [weak self] _, _ in // Remove .initial option to avoid triggering during initialization
windowsObservation = NSApp.observe(\.windows, options: [.new]) { [weak self] _, _ in
Task { @MainActor in Task { @MainActor in
// Add a small delay to let window state settle // Add a small delay to let window state settle
try? await Task.sleep(for: .milliseconds(50)) try? await Task.sleep(for: .milliseconds(50))
@ -119,6 +144,14 @@ final class DockIconManager: NSObject {
@objc @objc
private func dockPreferenceChanged(_ notification: Notification) { private func dockPreferenceChanged(_ notification: Notification) {
updateDockVisibility() // Only update if the specific dock preference changed
guard let userDefaults = notification.object as? UserDefaults,
userDefaults == UserDefaults.standard else { return }
// Ensure we're on main thread and add a small delay to avoid race conditions
Task { @MainActor in
try? await Task.sleep(for: .milliseconds(50))
self.updateDockVisibility()
}
} }
} }