Building a Floating Toolbar in SwiftUI for macOS - Lessons from a Desktop Agent
Building a Floating Toolbar in SwiftUI for macOS
Building a floating toolbar that feels native on macOS is harder than it looks. Apple Notes, Xcode, and Spotlight all have floating panels with smooth animations and correct behavior around fullscreen apps, multiple displays, and keyboard shortcuts. Getting there with SwiftUI requires solving a few specific problems.
Window Configuration
The foundation is an NSPanel subclass rather than a regular NSWindow. Panels have the right default behavior for floating UI - they do not appear in the window switcher, they can float above other windows, and they handle focus correctly.
Key settings:
styleMaskincludes.nonactivatingPanelso clicking the toolbar does not steal focus from the active applevelset to.floatingkeeps it above regular windowscollectionBehaviorincludes.canJoinAllSpacesand.fullScreenAuxiliaryfor proper multi-desktop and fullscreen behavior
Layout With @State
The toolbar needs to track its own size because SwiftUI does not give you a reliable way to measure content after layout. Use a GeometryReader inside the toolbar content to report the size back to an @State property, then apply that size as the frame of the hosting window.
This creates a feedback loop - content determines window size, which determines available space. Break the loop by using .fixedSize() on the toolbar content so it always reports its intrinsic size rather than expanding to fill available space.
Smooth Expand and Collapse
When the toolbar expands (showing additional controls) or collapses, animate both the SwiftUI content and the window frame together. Use withAnimation for the content and NSAnimationContext for the window frame, matching the duration and timing curve.
The trick is animating the window frame from the correct anchor point. If your toolbar is pinned to the top of the screen, the frame should grow downward. Calculate the new origin as currentOrigin.y - heightDelta and set the frame in the same animation block.
Keyboard Height Tracking
If the toolbar includes a text field, the macOS virtual keyboard (on iPads connected to a Mac or accessibility keyboards) can overlap it. Listen for NSApplication.didChangeScreenParametersNotification and adjust the toolbar position when the available screen area changes.
These patterns combine into a floating toolbar that feels like a native macOS component rather than a web-style overlay.
Fazm is an open source macOS AI agent. Open source on GitHub.