Fix dock icon not auto-switching with system dark mode (#1928)
* Fix dock icon not auto-switching with system dark mode The automatic icon mode relied on the asset catalog to handle appearance-based icon selection, but the compiled Assets.car does not include dark variant renditions for AppIcon. This meant setting applicationIconImage to nil had no effect — the icon stayed on the light variant regardless of system appearance. Replace the nil-reset approach with an active KVO observer on NSApp.effectiveAppearance that programmatically swaps between AppIconDark and AppIconLight images when in automatic mode. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Address review feedback: fix async race and harden singleton - Add guard in async callback to skip stale updates after stopObserving() - Add private init() to prevent external instantiation of singleton - Remove unused .new KVO option Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: CHE-3 <schumannzheng@gmail.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
960006e6d6
commit
4a8fd3d0fe
1 changed files with 34 additions and 3 deletions
|
|
@ -3695,14 +3695,14 @@ enum AppIconSettings {
|
|||
static func applyIcon(_ mode: AppIconMode) {
|
||||
switch mode {
|
||||
case .automatic:
|
||||
// Let the asset catalog handle appearance-based icon selection (macOS 15+).
|
||||
// Reset to the default bundle icon.
|
||||
NSApplication.shared.applicationIconImage = nil
|
||||
AppIconAppearanceObserver.shared.startObserving()
|
||||
case .light:
|
||||
AppIconAppearanceObserver.shared.stopObserving()
|
||||
if let icon = NSImage(named: "AppIconLight") {
|
||||
NSApplication.shared.applicationIconImage = icon
|
||||
}
|
||||
case .dark:
|
||||
AppIconAppearanceObserver.shared.stopObserving()
|
||||
if let icon = NSImage(named: "AppIconDark") {
|
||||
NSApplication.shared.applicationIconImage = icon
|
||||
}
|
||||
|
|
@ -3710,6 +3710,37 @@ enum AppIconSettings {
|
|||
}
|
||||
}
|
||||
|
||||
final class AppIconAppearanceObserver: NSObject {
|
||||
static let shared = AppIconAppearanceObserver()
|
||||
private var observation: NSKeyValueObservation?
|
||||
|
||||
private override init() { super.init() }
|
||||
|
||||
func startObserving() {
|
||||
applyIconForCurrentAppearance()
|
||||
guard observation == nil else { return }
|
||||
observation = NSApp.observe(\.effectiveAppearance, options: []) { [weak self] _, _ in
|
||||
DispatchQueue.main.async {
|
||||
guard let self, self.observation != nil else { return }
|
||||
self.applyIconForCurrentAppearance()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func stopObserving() {
|
||||
observation?.invalidate()
|
||||
observation = nil
|
||||
}
|
||||
|
||||
private func applyIconForCurrentAppearance() {
|
||||
let isDark = NSApp.effectiveAppearance.bestMatch(from: [.darkAqua, .aqua]) == .darkAqua
|
||||
let imageName = isDark ? "AppIconDark" : "AppIconLight"
|
||||
if let icon = NSImage(named: imageName) {
|
||||
NSApplication.shared.applicationIconImage = icon
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum QuitWarningSettings {
|
||||
static let warnBeforeQuitKey = "warnBeforeQuitShortcut"
|
||||
static let defaultWarnBeforeQuit = true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue