Уведомление об изменении активного документа в OS X?
Я использую NSWorkspace's NSWorkspaceDidActivateApplicationNotification
определить, когда изменяется активное приложение. я получил NSRunningApplication
из ключа userInfo уведомления.
Мне нужно получить уведомление при изменении активного документа. Я могу получить активный документ, используя рамки доступности NSAccessibilityDocumentAttribute
ключ через AXUIElementCopyAttributeValue()
,
Мне нужен более точный способ определения, когда документ изменяется, кроме опроса. Некоторые приложения используют несколько окон, в то время как другие используют одно окно с несколькими вкладками. С приложениями с вкладками окно возвращает текущий просмотренный документ.
Мне не нужно использовать рамки доступности. AppleScript (мост сценариев), по-видимому, также может получить документ окна, но инфраструктура доступности, похоже, работает с большим количеством приложений.
Меня волнует только активный документ, активное окно, активное приложение. То, что в данный момент ориентировано на систему.
Я тестировал с такими приложениями, как Sublime Text 2 и Xcode. Sublime возвращает текущую выбранную вкладку, где Xcode возвращает активный проект.
1 ответ
На самом деле я пытался достичь того же самого, и я думаю, что нашел решение для этого.
То, что я сделал, использовало CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
Это даст вам список всех активных окон, включая окна, которые вам, вероятно, не нужны.
Я забочусь только о окнах, которые имеют kCGWindowLayer = 0;
поэтому я отфильтровал окна, которые находятся на слое 0.
Вот как я это сделал:
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
NSMutableArray *data = [(__bridge NSArray *) windowList mutableCopy];
NSMutableArray *filteredData = [[NSMutableArray alloc] initWithCapacity:10];
for (NSMutableDictionary *theDict in data) {
id layer = [theDict objectForKey:(id)kCGWindowLayer];
if ([layer intValue] == 0) {
[filteredData addObject:theDict];
}
}
NSLog(@"window: %@", filteredData);
Это может быть самым элегантным решением, поэтому, если у кого-то есть идея получше, поделитесь. Также вам стоит взглянуть на демонстрационное приложение Apple Son of Grab.