So, with the comments from Alexander and Wileke I think I found a solution.
With NSWorkspace.shared.frontmostApplication
you can check, if Safari is currently active.
But as Wileke noted, that does not mean, that it has an active window.
Therefore, we use CGWindowListCopyWindowInfo
to first get all windows and check if at least one of them belongs to Safari by comparing the PIDs.
This way, we can safely say that Safari must have currently an active window that receives key events.
This must be true as there is now way that Safari is front most without any windows or that Safari as an window but is not front most at the same time.
Well, unless I missed something.
But for now it works.
Here is code I came up with:
func safariIsActive() -> Bool {
// Get the app that currently has the focus.
let frontApp = NSWorkspace.shared.frontmostApplication!
// Check if the front most app is Safari
if frontApp.bundleIdentifier == "com.apple.Safari" {
// If it is Safari, it still does not mean, that is receiving key events
// (i.e., has a window at the front).
// But what we can safely say is, that if Safari is the front most app
// and it has at least one window, it has to be the window that
// crrently receives key events.
let safariPID = frontApp.processIdentifier
// With this procedure, we get all available windows.
let options = CGWindowListOption(arrayLiteral: CGWindowListOption.excludeDesktopElements, CGWindowListOption.optionOnScreenOnly)
let windowListInfo = CGWindowListCopyWindowInfo(options, CGWindowID(0))
let windowInfoList = windowListInfo as NSArray? as? [[String: AnyObject]]
// Now that we have all available windows, we are going to check if at least one of them
// is owned by Safari.
for info in windowInfoList! {
let windowPID = info["kCGWindowOwnerPID"] as! UInt32
if windowPID == safariPID {
return true
}
}
}
return false
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…