user81909 user81909 - 3 months ago 17
Swift Question

Making a window visible over the loginwindow using "canBecomeVisibleWithoutLogin" and Swift on OS X 10.11

Hopefully someone can assist me.

I am trying to make a windowed application appear at the loginwindow on OSX 10.11, specifically at logout.

I am calling it using a logouthook script - I can see that the app is called on logout and the delay I have added to the application pauses the logout for 10 seconds but it doesn't actually display the main window.

The main window does display on login and I have tested removing the "canBecomeVisibleWithoutLogin" parameter which causes me to see errors in the system.log relating to the window not having permission to run over the loginwindow. Based on this, I believe the parameter is at least recognised.

I have looked around for examples on the web that use "canBecomeVisibleWithoutLogin" and I haven't been able to determine what step I am missing. I would appreciate any advice.

The code below is the only code I have added to the application which consists of a MainMenu.nib and a AppDelegate.swift.

I have also selected "visible at launch" and "Move to Active Space" in Xcode but this hasn't changed the behaviour at logout.

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

@IBOutlet weak var window: NSWindow!


func applicationWillFinishLaunching(notification: NSNotification) {

self.window.canBecomeVisibleWithoutLogin = true
self.window.orderFrontRegardless()
self.window.level = Int(CGWindowLevelForKey(CGWindowLevelKey.StatusWindowLevelKey))
}

func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application

self.window.display()

let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 10 * Int64(NSEC_PER_SEC))
dispatch_after(time, dispatch_get_main_queue()) {
//put your code which should be executed with a delay here

NSApplication.sharedApplication().terminate(self)
}
}

func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}

}

Answer

Setting the window level differently fixed it and I didn't need any other lines relating to self.window apart from self.window.level=2147483631

I am not sure of the full screen logout window level but I did try a couple of lower numbers and it still worked.

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

@IBOutlet weak var window: NSWindow!


func applicationWillFinishLaunching(notification: NSNotification) {


}

func applicationDidFinishLaunching(aNotification: NSNotification) {
    // Insert code here to initialize your application

    self.window.level=2147483631

    let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 10 * Int64(NSEC_PER_SEC))
    dispatch_after(time, dispatch_get_main_queue()) {
        //put your code which should be executed with a delay here

        NSApplication.sharedApplication().terminate(self)
    }
}

func applicationWillTerminate(aNotification: NSNotification) {
    // Insert code here to tear down your application
}


}