Window Visible on All Spaces (Including Other Fullscreen Apps)

Window visible on all spaces (including other fullscreen apps)

If you want a window to be visible on top of other fullscreen windows (in spaces), you should make an agent (accessory) application.
You can do it by setting LSUIElement key in the application’s Info.plist to 1 (YES)

If you still need a regular application you can do following:

  1. Create a separate agent (helper) application inside your main application bundle which will show your window. (There are plenty of good examples on how you can create such application)

  2. Play with NSApplicationActivationPolicy. You can try to change application's activation policy during a runtime.
    Swift 3:

    • NSApp.setActivationPolicy(.accessory) switch to agent(accessory)
    • NSApp.setActivationPolicy(.regular) switch to ordinary application

Keep in mind that .accessory policy hides the icon from Dock and you still need the code you have already:

window.collectionBehavior = .canJoinAllSpaces
window.level = Int(CGWindowLevelForKey(.floatingWindow))

Open window such that is shows on all desktops

This sounds like either NSWindowCollectionBehaviorCanJoinAllSpaces or NSWindowCollectionBehaviorStationary. Set it as the collectionBehavior of the window.

(You probably want to set the window level, too, but that's about ordering rather than collection/Spaces behavior. And if you have a Window menu, then you probably also want NSWindowCollectionBehaviorIgnoresCycle.)

How to force an NSWindow to be in front of every app? Even fullscreen apps

If you don't need to be visible with other apps' full-screen windows, it's not too hard.

First, to stay in front of everything else, just setLevel: with NSFloatingWindowLevel or higher. Experiment with the different values to see which seems appropriate to your needs.

Next, to stay in front even when the user changes Spaces, possibly including Exposé/Mission Control, setCollectionBehavior: with the appropriate pair of flags, or use the corresponding Spaces and Exposé settings in the Attributes Inspector if you're creating the window in the nib. Either Can Join All Spaces or Move to Active Space will make sure you stay visible on every space, in slightly different ways. You'll probably want Exposé set to Stationary, or possibly Transient, too. Again, try both ways and see.

However, Lion will hide both all-spaces and move-to-active-space windows when the user switches to a full-screen space or to Dashboard or Launchpad. And if you watch, you'll see that it does this in different ways for each of the three cases. And that Snow Leopard does things a little differently, and so does Mountain Lion.

If you want to solve that last problem, you need a bit of hackery—and different forms of hackery for each case and for each OS version. The basic trick is to catch the hide-related notifications and unhide yourself at the appropriate time.

How to make my app stay on top of fullscreen apps

Found the answer: The app delegate should look like this:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[window setLevel:kCGMainMenuWindowLevel-1];
[window setCollectionBehavior:NSWindowCollectionBehaviorStationary|NSWindowCollectionBehaviorCanJoinAllSpaces|NSWindowCollectionBehaviorFullScreenAuxiliary];
}

NSPanel is always on top of all other app windows

You do not pass nil, Nil, 0, or NULL to didEndSelector. Ever. You pass a selector to a method (-sheetDidClose:returnCode:contextInfo:) that you have declared. That you are passing something other than a selector makes whatever else you're doing to dismiss the sheet suspect. (You haven't said if the panel stays on top because it's never dismissed, but that's my assumption here.)

Take a look at Using Custom Sheets, which is Apple's own documentation on the subject.

Also, be sure that the panel you are using has its "Visible At Launch" flag turned off in IB.

Keeping window on top when switching spaces

Spaces is a pain. My solution was to register for a change notification like so:

[[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self 
selector:@selector(activeSpaceDidChange:)
name:NSWorkspaceActiveSpaceDidChangeNotification
object:nil];

Then in my WindowController class:

- (void) activeSpaceDidChange:(NSNotification *)aNotification {
if ([NSApp isActive]) [[self window] orderFront:self];
}


Related Topics



Leave a reply



Submit