diff --git a/Crisp/App/AppDelegate.swift b/Crisp/App/AppDelegate.swift index ed7e830..66d0276 100644 --- a/Crisp/App/AppDelegate.swift +++ b/Crisp/App/AppDelegate.swift @@ -239,6 +239,9 @@ class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate { // so no monitor is left bright with no boost and no DDC control. BrightnessBoostService.shared.prepareForTermination() // GammaService already handles CGDisplayRestoreColorSyncSettings via willTerminateNotification observer. + // Unmirror before the virtual displays die, so no panel is left showing + // a mirror of a display that just vanished. + MirroredModeService.shared.teardownAll() VirtualDisplayService.shared.destroyAll() } diff --git a/Crisp/Resources/Localizable.xcstrings b/Crisp/Resources/Localizable.xcstrings index 5f790e5..a8c6432 100644 --- a/Crisp/Resources/Localizable.xcstrings +++ b/Crisp/Resources/Localizable.xcstrings @@ -44,6 +44,16 @@ } } }, + "%@ (Crisp)" : { + "localizations" : { + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@(Crisp)" + } + } + } + }, "%@ color" : { "localizations" : { "zh-Hans" : { diff --git a/Crisp/Services/DisplayManager.swift b/Crisp/Services/DisplayManager.swift index 256ed6d..810e2fe 100644 --- a/Crisp/Services/DisplayManager.swift +++ b/Crisp/Services/DisplayManager.swift @@ -161,6 +161,11 @@ class DisplayManager: ObservableObject { BrightnessBoostService.shared.invalidate(for: $0) VolumeService.shared.invalidate(for: $0) } + // A mirrored physical unplugged, or its virtual master dying, must drop + // the mirror bookkeeping (and the orphan virtual with it). Checked against + // the online list, not removedIDs: the mirror virtual is never in + // `displays` (skipped below), so its death would not show up there. + MirroredModeService.shared.reconcile(online: newIDSet) // Diff-based refresh: keep existing DisplayInfo objects (preserves @Published state) let existingByID = Dictionary(uniqueKeysWithValues: displays.map { ($0.displayID, $0) }) @@ -170,6 +175,9 @@ class DisplayManager: ObservableObject { for i in 0..