Почему [NSRunningApplication activWithOptions:] возвращает NO
У меня проблема где [NSRunningApplication activateWithOptions:]
возвращается NO
когда нет очевидной причины, по которой он не сможет активировать приложение.
Это не дубликат -[NSRunningApplication activWithOptions:] не работает
Принятым ответом на этот вопрос является использование NSApplicationActivateIgnoringOtherApps
вместо NSApplicationActivateAllWindows
но это не является приемлемым ответом, поскольку эти два параметра предназначены для активации приложения по-разному, как подразумевают значения параметра.
В моем коде есть места, где [NSRunningApplication activateWithOptions:]
работает, однако при вызове через EventTap он почти всегда возвращает NO
независимо от использования NSApplicationActivateAllWindows
или же NSApplicationActivateIgnoringOtherApps
как option
аргумент. Причина, по которой я говорю "почти", всегда возвращается NO
потому что в первый раз это называется, оно работает. Все 2-й и последующие вызовы не выполняются.
Я в основном обрабатываю событие одним щелчком на значке приложения в Dock. Я использую EventTap, установленный на Dock
процесс, который был создан с CGEventTapCreateForPSN()
, В обратном вызове события я успешно определил process identifier
значка, который был нажат в Dock
, Идентификатор процесса был получен с помощью Accessibility API
,
Теперь мне нужно активировать приложение, поэтому я звоню:
BOOL result = NO;
NSRunningApplication *currentApp = [NSRunningApplication runningApplicationWithProcessIdentifier:pid];
if (currentApp) {
result = [currentApp activateWithOptions:NSApplicationActivateAllWindows];
}
В приведенном выше примере я убедился, что currentApp
действует, и это bundleIdentifier
, processIdentifier
и несколько других экземпляров Vars в RunningApplication
объект правильный.
Как упоминалось выше, независимо от NSApplicationActivationOptions
используется, приложение не активируется, а метод возвращает NO
, Опять же, иногда он срабатывает при самом первом щелчке, но не работает при всех последующих щелчках на значке дока любого приложения.
Кто-нибудь может объяснить, почему такой простой метод не работает? и, возможно, почему это будет работать только в первый раз, когда это называется? и почему он всегда работает, когда не выполняется из EventTap?
Я потратил несколько часов, пытаясь решить проблему, и единственное, что всегда работает, - это использование устаревшего метода SetFrontProcessWithOptions(&psn, 0);
вместо [NSRunningApplication activateWithOptions:NSApplicationActivateAllWindows]
,
Я попытался перевести звонок на [NSRunningApplication activateWithOptions:]
в dispatch_async
Я также пытался использовать очередь операций из EventTap, ни одна из которых не решает проблему. Наконец, я попытался отправить уведомление и позвонить [NSRunningApplication activateWithOptions:]
из обратного вызова уведомления, который также не удается. Это код в моем событии нажмите:
case kCGEventLeftMouseDown:
if (cgClickCount == 1) {
NSNumber *pidNumber = [NSNumber numberWithLong:actualPid];
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:pidNumber, @"pidNumber", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"DockApplicationClickedNotification" object:self userInfo:userInfo];
return NULL; /* swallows event */
}
break;
Любая помощь с благодарностью! Прикреплен экранный отладочный экран, показывающий, как успешно прошла 1-я попытка активировать приложение, щелкнув его значок в доке, и как последующие щелчки не активируют приложение.
ОБНОВЛЕНИЕ и наполовину решено: я определил почему [NSRunningApplication activateWithOptions:]
работает с 1-й попытки и не работает на 2-й и последующих попытках. Когда я в первый раз нажимаю на значок приложения в доке, мое приложение является активным приложением. При последующих щелчках по значку приложения активируется другое приложение. Таким образом, проблема здесь заключается в том, что [NSRunningApplication activateWithOptions:]
будет работать только в том случае, если мое приложение является передовым процессом.
Если я добавлю [NSApp activateIgnoringOtherApps:YES];
до звонка [NSRunningApplication activateWithOptions:]
, он последовательно работает как задумано, однако, есть мерцание меню из-за активации моего приложения только для того, чтобы затем активировать другое приложение. Таким образом, вопрос становится:
Есть ли способ получить [NSRunningApplication activateWithOptions:]
работать, когда мое приложение не является основным приложением? и является activateWithOptions:
должен работать таким образом?