swiftmacosswiftuiappkit

How to create a full screen overlay cover on macos using swift?


does anyone know how can I make this view cover the full screen without entering full screen mode? Essentially I just need to get this window to cover the top area where the menu bar is.

I have tried this answer from this SO post, but it does not work for me.

struct CoverView: View {
    
    @EnvironmentObject private var appDelegate: AppDelegate
    
    @AppStorage(SettingsKeys.popUpMenuMessage) var popUpMenuMessage: String = "Time to give me twenty!"
    
    var body: some View {
        VStack {
            Text(popUpMenuMessage)
            
            Button(action: closeScreen) {
                Label("Close", systemImage: "arrow.up")
            }
        }
    }
    
    func closeScreen() {
        appDelegate.hideCoverWindow()
    }
}

struct BlurEffectView: NSViewRepresentable {
    func makeNSView(context: Context) -> NSVisualEffectView {
        // called when view is first created
        let view = NSVisualEffectView()

        view.blendingMode = .behindWindow
        view.state = .active
        view.material = .underWindowBackground

        return view
    }

    func updateNSView(_ nsView: NSVisualEffectView, context: Context) {}
}
@main
struct GiveMeTwentyApp: App {
    // Accessing App Delegate
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {        
        Window("CoverView", id: "CoverViewWindow", content: {
            GeometryReader { geometry in
                CoverView()
                    .frame(minWidth: geometry.size.width, minHeight: geometry.size.height)
                    .background(BlurEffectView().ignoresSafeArea())
                    .environmentObject(appDelegate)
            }
            
        }).windowStyle(.hiddenTitleBar) // hiding title bar itself
    }
}
class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
    var coverWindow: NSWindow?
    
    func applicationDidFinishLaunching(_ notification: Notification) {
        configureCoverWindow()
    }
    
    
    func configureCoverWindow() {
        coverWindow = NSApplication.shared.windows.first(where: { $0.title == "CoverView" })
        coverWindow?.standardWindowButton(.closeButton)?.isHidden = true
        coverWindow?.standardWindowButton(.miniaturizeButton)?.isHidden = true
        coverWindow?.standardWindowButton(.zoomButton)?.isHidden = true
        coverWindow?.level = .popUpMenu
    }
}

This is what CoverView currently looks like:

enter image description here


Solution

  • You can force the window to be fullsized somewhere like in onAppear:

    .onAppear {
        guard let window = NSApplication.shared.windows.first(where: { $0.identifier?.rawValue == "CoverViewWindow" }) else { return } // 👈 Get the window by id
        window.styleMask = .fullSizeContentView // 👈 Prevents window moving by user and covers the dock and menubar
    
        if let screen = window.screen ?? NSScreen.main {
            window.setFrame(screen.frame, display: false) // 👈 Use `visibleFrame` if you like to preserve the dock and menubar WITHOUT letting the user move the window
        } else {
            window.zoom(self) // 👈 Fallback
        }
    }