After resigning active state (going to the background), the mainWindow
property of the main window in the app returns false.
Nevertheless, I need a to find that window even when my app is not active, so I came up with the following code, which works:
public let App = NSApplication.sharedApplication() // just some sugar
public extension NSApplication {
public func frontmostWindow(_ accept: (NSWindow -> Bool)? = nil) -> NSWindow? {
for windowNumber in NSWindow.windowNumbersWithOptions(0) as? [Int] ?? [] {
if let window = windowWithWindowNumber(windowNumber) {
if let accept = accept {
if accept(window) {
return window
}
} else {
return window
}
}
}
return nil
}
}
With this, I can now get the first window of my app in the current ordering that passes the provided predicate check (accept: NSWindow -> Bool
). This is because I normally would not be interested in the menu bar or the status item, which all have associated windows that belong to my app (which is what I would get if I do not pass any predicate). As an example, say I have some:
class PimpedUpWindow: NSWindow, ExtraTranslucent {}
the frontmost instance of which I wish to find after the app launches and is no longer the active app. Using the extension above I can:
App.frontmostWindow { $0 is PimpedUpWindow }
or
App.frontmostWindow { $0 is ExtraTranslucent }
Of course, I can provide any other predicate of type NSWindow -> Bool
, but I figure I will often enough want to just check the type or protocol conformance. So I might as well add two convenience methods for just those occasions:
public extension NSApplication {
public func frontmost <T> (windowOfType: T.Type) -> T? {
return frontmostWindow { $0 is T } as? T
}
public func frontmostWindow <P> (conformingTo: P.Type) -> NSWindow? {
return frontmostWindow { $0 is P }
}
}
Now, I can simply:
App.frontmost(PimpedUpWindow)
Which actually returns a PimpedUpWindow?
, and:
App.frontmostWindow(ExtraTranslucent)
which returns an NSWindow?
.
All ideas, criticisms, and comments very welcome!