#swift #macos #cocoa #safari-app-extension
#swift #macos #какао #safari-app-extension
Вопрос:
В настоящее время я разрабатываю расширение приложения Safari, которое состоит из двух частей:
- Приложение только для строки состояния хоста
- Расширение Safari
Далее хост-приложение предлагает глобальный ярлык, который открывает всплывающее окно в строке состояния. Однако я хочу проверить, какое окно приложения в данный момент активно, потому что я не хочу открывать всплывающее окно, если окно Safari в данный момент активно. Есть ли какой-либо способ узнать с помощью Swift, какое окно приложения в данный момент активно?
Спасибо за вашу помощь.
Комментарии:
1. Проверьте developer.apple.com/documentation/appkit/nsworkspace
2. Что делать, если Safari активен без окон?
Ответ №1:
Итак, с комментариями Александра и Вилеке, я думаю, что нашел решение.
С NSWorkspace.shared.frontmostApplication
помощью вы можете проверить, активен ли Safari в данный момент. Но, как отметил Уилеке, это не означает, что у него есть активное окно. Поэтому мы CGWindowListCopyWindowInfo
сначала получаем все окна и проверяем, принадлежит ли хотя бы одно из них Safari, сравнивая PID.
Таким образом, мы можем с уверенностью сказать, что Safari в настоящее время должно иметь активное окно, которое получает ключевые события. Это должно быть правдой, поскольку теперь существует способ, при котором Safari является самым передним без каких-либо окон или Safari в качестве окна, но в то же время не является самым передним.
Ну, если я что-то не пропустил. Но пока это работает.
Вот код, который я придумал:
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
}