Overlay window above all windows, even when moving spaces

Hi!

I would like to overlay a macOS application window above all windows, even when moving spaces or moving to a fullscreen app, similar in function to the DropOver app for macOS.

What I have tried:

Overwriting the default app delegate in SwiftUI and creating the NSWindow myself.

Then setting the window.collectionBehavior to [.canJoinAllApplications, .canJoinAllSpaces, .fullScreenAuxiliary] and the window.level to .floating or .statusBar. This works for moving between Spaces, but still does not display above apps in fullscreen mode.

I also registered a notification observer for NSWorkspace.activeSpaceDidChangeNotification, where I call window.orderFrontRegardless() to always have my window frontmost. Still not displaying above fullscreen apps.

What am I missing to make this work?

Best regards

Answered by DTS Engineer in 887785022

Your collectionBehavior is close — canJoinAllApplications is the right option for spanning other apps' Spaces — but two other pieces are missing for floating above full-screen apps:

1. Accessory activation policy. macOS doesn't layer regular foreground apps above other apps' full-screen Spaces. Overlay utilities like DropOver use NSApplicationActivationPolicyAccessory, which removes the Dock icon and app menu bar (most overlay utilities add a menu bar status item in their place) and lets the app's windows appear above full-screen content from other apps. In your app delegate's applicationDidFinishLaunching:

NSApp.setActivationPolicy(.accessory)

2. NSPanel with .nonactivatingPanel. An NSWindow activates its app when ordered front, which can cause a full-screen app to exit its Space. An NSPanel with the .nonactivatingPanel style mask doesn't.

Full panel setup:

let panel = NSPanel(
    contentRect: NSRect(x: 200, y: 200, width: 260, height: 140),
    styleMask: [.nonactivatingPanel, .titled, .closable],
    backing: .buffered,
    defer: false
)
panel.isFloatingPanel = true
panel.hidesOnDeactivate = false
panel.level = .screenSaver
panel.collectionBehavior = [
    .canJoinAllSpaces,
    .canJoinAllApplications,
    .fullScreenAuxiliary,
    .stationary
]
panel.orderFrontRegardless()

A couple of notes:

  • You need .screenSaver (level 1000) — .floating (3) and .statusBar (25) both sit below full-screen content.
  • With this configuration, you can remove your activeSpaceDidChangeNotification observer. The collection behavior keeps the panel visible on every Space — including other apps' full-screen Spaces — so the manual orderFrontRegardless() on space change is unnecessary.

I tested this combination in macOS 26 against Safari, QuickTime Player, and a YouTube video in full screen, and the panel stayed on top in all three cases.

Accepted Answer

Your collectionBehavior is close — canJoinAllApplications is the right option for spanning other apps' Spaces — but two other pieces are missing for floating above full-screen apps:

1. Accessory activation policy. macOS doesn't layer regular foreground apps above other apps' full-screen Spaces. Overlay utilities like DropOver use NSApplicationActivationPolicyAccessory, which removes the Dock icon and app menu bar (most overlay utilities add a menu bar status item in their place) and lets the app's windows appear above full-screen content from other apps. In your app delegate's applicationDidFinishLaunching:

NSApp.setActivationPolicy(.accessory)

2. NSPanel with .nonactivatingPanel. An NSWindow activates its app when ordered front, which can cause a full-screen app to exit its Space. An NSPanel with the .nonactivatingPanel style mask doesn't.

Full panel setup:

let panel = NSPanel(
    contentRect: NSRect(x: 200, y: 200, width: 260, height: 140),
    styleMask: [.nonactivatingPanel, .titled, .closable],
    backing: .buffered,
    defer: false
)
panel.isFloatingPanel = true
panel.hidesOnDeactivate = false
panel.level = .screenSaver
panel.collectionBehavior = [
    .canJoinAllSpaces,
    .canJoinAllApplications,
    .fullScreenAuxiliary,
    .stationary
]
panel.orderFrontRegardless()

A couple of notes:

  • You need .screenSaver (level 1000) — .floating (3) and .statusBar (25) both sit below full-screen content.
  • With this configuration, you can remove your activeSpaceDidChangeNotification observer. The collection behavior keeps the panel visible on every Space — including other apps' full-screen Spaces — so the manual orderFrontRegardless() on space change is unnecessary.

I tested this combination in macOS 26 against Safari, QuickTime Player, and a YouTube video in full screen, and the panel stayed on top in all three cases.

Thanks for the quick reply!

I was missing the NSPanel bit!

I forgot to mention that I added the Application is agent (LSUIElement) key to the info.plist which seems to be equivalent to your first point.

Now everything seems to work as you've stated. I tested those scenarios as well and it always stays on top!

Overlay window above all windows, even when moving spaces
 
 
Q