chore: rename project to clawdbot
This commit is contained in:
116
apps/macos/Sources/Clawdbot/DockIconManager.swift
Normal file
116
apps/macos/Sources/Clawdbot/DockIconManager.swift
Normal file
@@ -0,0 +1,116 @@
|
||||
import AppKit
|
||||
|
||||
/// Central manager for Dock icon visibility.
|
||||
/// Shows the Dock icon while any windows are visible, regardless of user preference.
|
||||
final class DockIconManager: NSObject, @unchecked Sendable {
|
||||
static let shared = DockIconManager()
|
||||
|
||||
private var windowsObservation: NSKeyValueObservation?
|
||||
private let logger = Logger(subsystem: "com.clawdbot", category: "DockIconManager")
|
||||
|
||||
override private init() {
|
||||
super.init()
|
||||
self.setupObservers()
|
||||
Task { @MainActor in
|
||||
self.updateDockVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.windowsObservation?.invalidate()
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
func updateDockVisibility() {
|
||||
Task { @MainActor in
|
||||
guard NSApp != nil else {
|
||||
self.logger.warning("NSApp not ready, skipping Dock visibility update")
|
||||
return
|
||||
}
|
||||
|
||||
let userWantsDockHidden = !UserDefaults.standard.bool(forKey: showDockIconKey)
|
||||
let visibleWindows = NSApp?.windows.filter { window in
|
||||
window.isVisible &&
|
||||
window.frame.width > 1 &&
|
||||
window.frame.height > 1 &&
|
||||
!window.isKind(of: NSPanel.self) &&
|
||||
"\(type(of: window))" != "NSPopupMenuWindow" &&
|
||||
window.contentViewController != nil
|
||||
} ?? []
|
||||
|
||||
let hasVisibleWindows = !visibleWindows.isEmpty
|
||||
if !userWantsDockHidden || hasVisibleWindows {
|
||||
NSApp?.setActivationPolicy(.regular)
|
||||
} else {
|
||||
NSApp?.setActivationPolicy(.accessory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func temporarilyShowDock() {
|
||||
Task { @MainActor in
|
||||
guard NSApp != nil else {
|
||||
self.logger.warning("NSApp not ready, cannot show Dock icon")
|
||||
return
|
||||
}
|
||||
NSApp.setActivationPolicy(.regular)
|
||||
}
|
||||
}
|
||||
|
||||
private func setupObservers() {
|
||||
Task { @MainActor in
|
||||
guard let app = NSApp else {
|
||||
self.logger.warning("NSApp not ready, delaying Dock observers")
|
||||
try? await Task.sleep(for: .milliseconds(200))
|
||||
self.setupObservers()
|
||||
return
|
||||
}
|
||||
|
||||
self.windowsObservation = app.observe(\.windows, options: [.new]) { [weak self] _, _ in
|
||||
Task { @MainActor in
|
||||
try? await Task.sleep(for: .milliseconds(50))
|
||||
self?.updateDockVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(self.windowVisibilityChanged),
|
||||
name: NSWindow.didBecomeKeyNotification,
|
||||
object: nil)
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(self.windowVisibilityChanged),
|
||||
name: NSWindow.didResignKeyNotification,
|
||||
object: nil)
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(self.windowVisibilityChanged),
|
||||
name: NSWindow.willCloseNotification,
|
||||
object: nil)
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(self.dockPreferenceChanged),
|
||||
name: UserDefaults.didChangeNotification,
|
||||
object: nil)
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
private func windowVisibilityChanged(_: Notification) {
|
||||
Task { @MainActor in
|
||||
self.updateDockVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
private func dockPreferenceChanged(_ notification: Notification) {
|
||||
guard let userDefaults = notification.object as? UserDefaults,
|
||||
userDefaults == UserDefaults.standard
|
||||
else { return }
|
||||
|
||||
Task { @MainActor in
|
||||
self.updateDockVisibility()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user