Issue #1025
macOS windows look best when they blend with the desktop — the translucent, frosted-glass look that makes panels feel native rather than opaque blocks of UI. There are two ways to achieve this depending on your deployment target.
NSVisualEffectView
Before macOS 26, NSVisualEffectView is the standard tool. It composites your content over the desktop using one of several material styles — sidebar, popover, hudWindow, and more — each producing a slightly different frosted appearance.
The key settings are blendingMode and state. Setting blendingMode to .behindWindow pulls pixels from the desktop wallpaper and windows behind yours. Setting state to .active keeps the effect live even when the window loses focus.
Corner radius requires a mask image rather than setting layer.cornerRadius directly. The mask is a simple rounded-rect drawn into an NSImage:
static func mask(cornerRadius radius: CGFloat) -> NSImage {
NSImage(
size: NSSize(width: radius * 2, height: radius * 2),
flipped: false,
drawingHandler: { rect in
NSBezierPath(roundedRect: rect, xRadius: radius, yRadius: radius).fill()
NSColor.black.set()
return true
}
)
}
With that in hand, you can build a helper that wraps any view in a visual effect container:
extension NSVisualEffectView {
static func withSubview(
_ subview: NSView,
material: NSVisualEffectView.Material = .popover,
cornerRadius: CGFloat
) -> NSVisualEffectView {
let view = NSVisualEffectView()
view.blendingMode = .behindWindow
view.state = .active
view.material = material
view.maskImage = NSImage.mask(cornerRadius: cornerRadius)
view.addSubview(subview)
subview.autoresizingMask = [.width, .height]
return view
}
}
Assign this as the window’s contentView and the effect covers the entire window surface.
NSGlassEffectView
macOS 26 introduces NSGlassEffectView, a first-class glass container that replaces the mask-image approach with a direct cornerRadius property. It also accepts a contentView, so you embed your hosted SwiftUI view directly rather than adding it as a subview.
let glass = NSGlassEffectView()
glass.cornerRadius = 20
glass.style = .regular
glass.clipsToBounds = true
glass.contentView = NSHostingView(rootView: myView)
window.backgroundColor = .clear
window.contentView = glass
Setting window.backgroundColor = .clear is required — without it the window draws its own background over the glass effect
Start the conversation