From 8d4f47234871172d41d3eb31923b2cddaecbfeed Mon Sep 17 00:00:00 2001 From: Arkadiusz Fal Date: Mon, 6 Jul 2026 09:36:49 +0200 Subject: [PATCH] Unify macOS content view backgrounds with opaque window background Views without an explicit background sat on the translucent window material, which picks up a wallpaper tint (bluish in dark mode) and clashed with views drawing windowBackgroundColor, making the video info header gradient fade visibly mismatch. Add opaqueWindowBackground() and apply it centrally in NavigationDestinationHandlerModifier to both stack roots and pushed destinations, plus VideoInfoView for presentations outside navigation stacks. Claude-Session: https://claude.ai/code/session_0154KH8RAVAvm6iVanhmoW8o --- .../Navigation/NavigationDestination.swift | 14 +++++--- .../Components/OpaqueWindowBackground.swift | 33 +++++++++++++++++++ Yattee/Views/Video/VideoInfoView.swift | 3 ++ 3 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 Yattee/Views/Components/OpaqueWindowBackground.swift diff --git a/Yattee/Services/Navigation/NavigationDestination.swift b/Yattee/Services/Navigation/NavigationDestination.swift index adc69dc7..8d0cfd42 100644 --- a/Yattee/Services/Navigation/NavigationDestination.swift +++ b/Yattee/Services/Navigation/NavigationDestination.swift @@ -184,13 +184,17 @@ private struct MediaSourceByIDView: View { struct NavigationDestinationHandlerModifier: ViewModifier { func body(content: Content) -> some View { content + .opaqueWindowBackground() .navigationDestination(for: NavigationDestination.self) { destination in - if let transitionID = destination.transitionID { - destination.view() - .zoomTransitionDestination(id: transitionID) - } else { - destination.view() + Group { + if let transitionID = destination.transitionID { + destination.view() + .zoomTransitionDestination(id: transitionID) + } else { + destination.view() + } } + .opaqueWindowBackground() } } } diff --git a/Yattee/Views/Components/OpaqueWindowBackground.swift b/Yattee/Views/Components/OpaqueWindowBackground.swift new file mode 100644 index 00000000..c2fe528e --- /dev/null +++ b/Yattee/Views/Components/OpaqueWindowBackground.swift @@ -0,0 +1,33 @@ +// +// OpaqueWindowBackground.swift +// Yattee +// +// Unified opaque background for main content views on macOS. +// + +import SwiftUI + +/// Applies an opaque window background on macOS. +/// +/// Without an explicit background, content sits on the translucent window +/// material, which picks up a wallpaper tint (often bluish in dark mode) and +/// clashes with views that draw `windowBackgroundColor` themselves (lists, +/// gradient fades). No-op on other platforms. +struct OpaqueWindowBackgroundModifier: ViewModifier { + func body(content: Content) -> some View { + #if os(macOS) + content + .background(Color(nsColor: .windowBackgroundColor).ignoresSafeArea()) + #else + content + #endif + } +} + +extension View { + /// Gives the view an opaque window background on macOS so all main content + /// views share the same background color. No-op on iOS/tvOS. + func opaqueWindowBackground() -> some View { + modifier(OpaqueWindowBackgroundModifier()) + } +} diff --git a/Yattee/Views/Video/VideoInfoView.swift b/Yattee/Views/Video/VideoInfoView.swift index 985bba6f..f1a63e80 100644 --- a/Yattee/Views/Video/VideoInfoView.swift +++ b/Yattee/Views/Video/VideoInfoView.swift @@ -259,6 +259,9 @@ struct VideoInfoView: View { videoContent } } + // Opaque background so the header gradient (which fades to windowBackgroundColor) + // blends seamlessly even when presented outside a navigation stack. + .opaqueWindowBackground() .task { await loadInitialVideoIfNeeded() }