Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Window visible on all spaces (including other fullscreen apps)

I'm trying to make a window (NSWindow) visible on all the spaces including other full screen app windows. I've been trying to set a higher window level as well as playing with expose and spaces settings in the inspector. I found some solutions here, but they do not work. At least on El Capitan.

Here is a sample code to test:

let window = NSWindow(contentRect: NSRect(x: 300, y: 300, width: 200, height: 200), styleMask: NSBorderlessWindowMask, backing: .Buffered, `defer`: true)
window.backgroundColor = NSColor.greenColor()
window.level = Int(CGWindowLevelForKey(.FloatingWindowLevelKey))
window.collectionBehavior = [.CanJoinAllSpaces, .Transient]
window.makeKeyAndOrderFront(nil)

Now it displays the window on all the desktop spaces but it does not display it over the full screen windows of other apps.

like image 777
Marcin Krzywonos Avatar asked Nov 21 '15 16:11

Marcin Krzywonos


2 Answers

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))

like image 88
Artur Avatar answered Oct 08 '22 11:10

Artur


You're on the right track in a way, you need to set your window object's level to one level above the Shield Window's to be in the the forefront:

        window.level = Int(CGShieldingWindowLevel()) + 1

Do note that this technique is not really recommended as some problems might arise from the interaction between full-screen graphics (OpenGL full-screen drawing contexts is an example) and the graphics hardware; but it's your best bet if you want to ensure overlay on top of all other applications.

like image 39
Joseph Junior Sfeir Avatar answered Oct 08 '22 11:10

Joseph Junior Sfeir