Ver código fonte

Fix fullscreen window chrome to keep light appearance.

Ensure hidden title bar windows preserve a light toolbar/traffic-light style in fullscreen and extend the app background into the top safe area for consistent theming.
AhtashamShahzad1 1 mês atrás
pai
commit
7941a8152c

+ 4 - 1
gramora/App/GramoraApp.swift

@@ -7,8 +7,11 @@ struct GramoraApp: App {
             MainView()
                 .frame(minWidth: AppTheme.windowMinWidth, minHeight: AppTheme.windowMinHeight)
                 .initialWindowSize(width: AppTheme.windowWidth, height: AppTheme.windowHeight)
+                .configureWindowChrome()
+                .preferredColorScheme(.light)
+                .lightWindowToolbarBackground()
         }
         .windowStyle(.hiddenTitleBar)
-        .windowToolbarStyle(.unifiedCompact)
+        .windowToolbarStyle(.unifiedCompact(showsTitle: false))
     }
 }

+ 106 - 0
gramora/Utilities/WindowChromeConfigurator.swift

@@ -0,0 +1,106 @@
+import AppKit
+import SwiftUI
+
+struct WindowChromeConfigurator: ViewModifier {
+    func body(content: Content) -> some View {
+        content.background(WindowChromeAccessor())
+    }
+}
+
+private struct WindowChromeAccessor: NSViewRepresentable {
+    func makeCoordinator() -> Coordinator {
+        Coordinator()
+    }
+
+    func makeNSView(context: Context) -> NSView {
+        let view = NSView(frame: .zero)
+        DispatchQueue.main.async {
+            context.coordinator.configure(window: view.window)
+        }
+        return view
+    }
+
+    func updateNSView(_ nsView: NSView, context: Context) {
+        DispatchQueue.main.async {
+            context.coordinator.configure(window: nsView.window)
+        }
+    }
+
+    final class Coordinator {
+        private weak var observedWindow: NSWindow?
+        private var observers: [NSObjectProtocol] = []
+
+        func configure(window: NSWindow?) {
+            guard let window else { return }
+
+            if window !== observedWindow {
+                teardown()
+                observedWindow = window
+                setupObservers(for: window)
+            }
+
+            applyChrome(to: window)
+        }
+
+        private func applyChrome(to window: NSWindow) {
+            window.styleMask.insert(.fullSizeContentView)
+            window.titlebarAppearsTransparent = true
+            window.titleVisibility = .hidden
+            window.isMovableByWindowBackground = true
+            window.titlebarSeparatorStyle = .none
+            window.title = ""
+            window.appearance = NSAppearance(named: .aqua)
+            window.backgroundColor = NSColor(AppTheme.background)
+        }
+
+        private func setupObservers(for window: NSWindow) {
+            let center = NotificationCenter.default
+            let names: [Notification.Name] = [
+                NSWindow.didBecomeKeyNotification,
+                NSWindow.didEnterFullScreenNotification,
+                NSWindow.willExitFullScreenNotification,
+                NSWindow.didExitFullScreenNotification,
+                NSWindow.didResizeNotification,
+            ]
+
+            for name in names {
+                let observer = center.addObserver(
+                    forName: name,
+                    object: window,
+                    queue: .main
+                ) { [weak self] notification in
+                    guard let self,
+                          let window = notification.object as? NSWindow else { return }
+                    self.applyChrome(to: window)
+                }
+                observers.append(observer)
+            }
+        }
+
+        private func teardown() {
+            let center = NotificationCenter.default
+            observers.forEach { center.removeObserver($0) }
+            observers.removeAll()
+        }
+
+        deinit {
+            teardown()
+        }
+    }
+}
+
+extension View {
+    func configureWindowChrome() -> some View {
+        modifier(WindowChromeConfigurator())
+    }
+
+    @ViewBuilder
+    func lightWindowToolbarBackground() -> some View {
+        if #available(macOS 13.0, *) {
+            toolbarBackground(AppTheme.background, for: .windowToolbar)
+                .toolbarBackground(.visible, for: .windowToolbar)
+        } else {
+            self
+        }
+    }
+}

+ 4 - 1
gramora/Views/MainView.swift

@@ -22,7 +22,10 @@ struct MainView: View {
             }
             .frame(maxWidth: .infinity, maxHeight: .infinity)
         }
-        .background(AppTheme.background)
+        .background {
+            AppTheme.background
+                .ignoresSafeArea(edges: .top)
+        }
     }
 
     @ViewBuilder