Fix cross-window theme background gating after jump-to-unread (#861)

* Fix cross-window theme background gating

* Handle owning-manager nil-selection theme edge case

* Simplify window background gating helper
This commit is contained in:
Lawrence Chen 2026-03-04 02:48:06 -08:00 committed by GitHub
parent ace539326f
commit 79cfe2d168
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 120 additions and 1 deletions

View file

@ -2981,9 +2981,38 @@ class GhosttyNSView: NSView, NSUserInterfaceValidations {
}
}
// Theme/background application is window-local. During cross-window workspace
// switches (e.g. jump-to-unread), the global active tab manager can lag behind.
// Prefer the owning window's selected workspace when available.
static func shouldApplyWindowBackground(
surfaceTabId: UUID?,
owningManagerExists: Bool,
owningSelectedTabId: UUID?,
activeSelectedTabId: UUID?
) -> Bool {
guard let surfaceTabId else { return true }
if owningManagerExists {
guard let owningSelectedTabId else { return true }
return owningSelectedTabId == surfaceTabId
}
if let activeSelectedTabId {
return activeSelectedTabId == surfaceTabId
}
return true
}
func applyWindowBackgroundIfActive() {
guard let window else { return }
if let tabId, let selectedId = AppDelegate.shared?.tabManager?.selectedTabId, tabId != selectedId {
let appDelegate = AppDelegate.shared
let owningManager = tabId.flatMap { appDelegate?.tabManagerFor(tabId: $0) }
let owningSelectedTabId = owningManager?.selectedTabId
let activeSelectedTabId = owningManager == nil ? appDelegate?.tabManager?.selectedTabId : nil
guard Self.shouldApplyWindowBackground(
surfaceTabId: tabId,
owningManagerExists: owningManager != nil,
owningSelectedTabId: owningSelectedTabId,
activeSelectedTabId: activeSelectedTabId
) else {
return
}
applySurfaceBackground()

View file

@ -659,6 +659,96 @@ final class WindowTransparencyDecisionTests: XCTestCase {
}
}
final class WindowBackgroundSelectionGateTests: XCTestCase {
func testShouldApplyWindowBackgroundUsesOwningWindowSelectionWhenAvailable() {
let tabId = UUID()
let activeSelectedTabId = UUID()
XCTAssertTrue(
GhosttyNSView.shouldApplyWindowBackground(
surfaceTabId: tabId,
owningManagerExists: true,
owningSelectedTabId: tabId,
activeSelectedTabId: activeSelectedTabId
)
)
}
func testShouldApplyWindowBackgroundRejectsWhenOwningSelectionDiffers() {
let tabId = UUID()
XCTAssertFalse(
GhosttyNSView.shouldApplyWindowBackground(
surfaceTabId: tabId,
owningManagerExists: true,
owningSelectedTabId: UUID(),
activeSelectedTabId: tabId
)
)
}
func testShouldApplyWindowBackgroundAllowsWhenOwningManagerSelectionIsTemporarilyNil() {
let tabId = UUID()
XCTAssertTrue(
GhosttyNSView.shouldApplyWindowBackground(
surfaceTabId: tabId,
owningManagerExists: true,
owningSelectedTabId: nil,
activeSelectedTabId: UUID()
)
)
}
func testShouldApplyWindowBackgroundFallsBackToActiveSelection() {
let tabId = UUID()
XCTAssertTrue(
GhosttyNSView.shouldApplyWindowBackground(
surfaceTabId: tabId,
owningManagerExists: false,
owningSelectedTabId: nil,
activeSelectedTabId: tabId
)
)
XCTAssertFalse(
GhosttyNSView.shouldApplyWindowBackground(
surfaceTabId: tabId,
owningManagerExists: false,
owningSelectedTabId: nil,
activeSelectedTabId: UUID()
)
)
}
func testShouldApplyWindowBackgroundAllowsWhenNoSelectionContext() {
XCTAssertTrue(
GhosttyNSView.shouldApplyWindowBackground(
surfaceTabId: UUID(),
owningManagerExists: false,
owningSelectedTabId: nil,
activeSelectedTabId: nil
)
)
XCTAssertTrue(
GhosttyNSView.shouldApplyWindowBackground(
surfaceTabId: nil,
owningManagerExists: false,
owningSelectedTabId: nil,
activeSelectedTabId: nil
)
)
XCTAssertTrue(
GhosttyNSView.shouldApplyWindowBackground(
surfaceTabId: nil,
owningManagerExists: true,
owningSelectedTabId: UUID(),
activeSelectedTabId: UUID()
)
)
}
}
final class NotificationBurstCoalescerTests: XCTestCase {
func testSignalsInSameBurstFlushOnce() {
let coalescer = NotificationBurstCoalescer(delay: 0.01)