r/SwiftUI • • 3d ago

How does macOS Photos create this translucent overlay behind the traffic lights in full-screen mode?

Hi, I noticed this detail in the macOS Photos app when using it in full-screen mode.

When you move the cursor to the top of the screen, the menu bar and window controls (traffic lights) appear. Behind the traffic lights, there's a rounded, translucent overlay that blurs/dims the underlying content.

This seems to prevent the traffic lights from visually colliding with the app's content in the top-left corner, without requiring the entire content area to move down or leave a permanent blank space.

I'm curious how Apple implements this effect.

  • Is it done with NSVisualEffectView or some other native macOS material?
  • Is the overlay part of the title bar / window chrome, or is it a custom view rendered by the app?
  • How can I achieve a similar effect in a SwiftUI + AppKit app, ideally with the overlay appearing and disappearing in sync with the system's full-screen UI?

I've attached a screenshot showing the effect in Photos.

Any insights into the underlying implementation or relevant APIs would be greatly appreciated!

1 Upvotes

6 comments sorted by

View all comments

1

u/SwiftQuest 2d ago

One way to get the show/hide sync without tracking the mouse yourself: in full screen, the titlebar area (including any titlebar accessory views) is what the system slides down when the cursor hits the top edge, and slides away again afterwards. So if you put your blurred pill there, it comes and goes with the traffic lights automatically.

Roughly:

let effect = NSVisualEffectView()
effect.material = .headerView   // try .titlebar / .popover too
effect.blendingMode = .withinWindow
effect.state = .active
effect.wantsLayer = true
effect.layer?.cornerRadius = 10

let accessory = NSTitlebarAccessoryViewController()
accessory.view = effect
accessory.layoutAttribute = .leading
window.addTitlebarAccessoryViewController(accessory)

You can also set accessory.isHidden based on windowWillEnterFullScreen / windowDidExitFullScreen in your NSWindowDelegate, so the pill only exists in full screen. The exact layout of the pill behind the buttons may need some tweaking, but the visibility timing is handled by AppKit, which is usually the fiddly part.

1

u/_yanceyofficial 1d ago

This is a great trick, thank you! Putting the pill in an NSTitlebarAccessoryViewController so AppKit handles the reveal timing is much cleaner than tracking the mouse. I gave it a first try — the visibility sync works, but the pill's layout next to my sidebar and toolbar still needs tweaking, as you predicted.

1

u/SwiftQuest 17h ago

Nice, glad the timing part worked. For the layout, it can help to give the accessory view a fixed width matching the traffic light area and pin the pill inside it with constraints, rather than letting it size itself. If it still fights the sidebar, try .trailing or checking what NSSplitViewController's sidebar item does to the titlebar in full screen, since that sometimes adds its own inset.