当没有明显原因导致应用程序无法激活时,我遇到了[NSRunningApplication activateWithOptions:]
返回问题。NO
这不是-[NSRunningApplication activateWithOptions:] 不工作的副本
该问题的公认答案是使用NSApplicationActivateIgnoringOtherApps
代替,NSApplicationActivateAllWindows
但这不是可接受的答案,因为这两个选项旨在以选项值所暗示的不同方式激活应用程序。
我的代码中有一些地方[NSRunningApplication activateWithOptions:]
可以工作,但是当通过 EventTap 调用它时,它几乎总是返回NO
,而不管使用NSApplicationActivateAllWindows
或NSApplicationActivateIgnoringOtherApps
作为option
参数。我说“几乎”总是返回NO
的原因是因为第一次调用它时,它确实有效。所有第 2 次和后续调用均失败。
我基本上是在处理 Dock 中应用程序图标上的单击事件。我正在使用安装在Dock
使用CGEventTapCreateForPSN()
. 在事件点击回调中,我已成功确定process identifier
在Dock
. 进程 ID 是使用Accessibility API
.
现在我需要激活应用程序,所以我调用:
BOOL result = NO;
NSRunningApplication *currentApp = [NSRunningApplication runningApplicationWithProcessIdentifier:pid];
if (currentApp) {
result = [currentApp activateWithOptions:NSApplicationActivateAllWindows];
}
在上面的示例中,我已经验证了 thatcurrentApp
是有效的,并且 that bundleIdentifier
和 对象中processIdentifier
的其他一些实例 varRunningApplication
是正确的。
如上所述,无论NSApplicationActivationOptions
使用什么,应用程序都不会激活,并且方法返回NO
. 同样,它偶尔会在第一次单击时起作用,但在所有后续单击任何应用程序的停靠图标时都会失败。
谁能解释为什么这么简单的方法会失败?可能为什么它只在第一次被调用时才起作用?为什么它在不从 EventTap 执行时总是有效?
我花了几个小时试图解决这个问题,唯一总是有效的方法是使用不推荐使用的方法SetFrontProcessWithOptions(&psn, 0);
而不是[NSRunningApplication activateWithOptions:NSApplicationActivateAllWindows]
.
我尝试将调用包装到[NSRunningApplication activateWithOptions:]
within 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;
非常感谢任何帮助!附加的调试屏幕抓取显示了第一次尝试通过单击其停靠图标来激活应用程序是如何成功的,以及后续单击如何无法激活应用程序。
更新并解决了一半:
我已经确定了为什么[NSRunningApplication activateWithOptions:]
在第一次尝试时有效而在第二次和后续尝试中失败。第一次单击 Dock 中的应用程序图标时,我的应用程序是活动应用程序。在随后单击应用程序图标时,其他一些应用程序处于活动状态。所以这里的问题似乎是[NSRunningApplication activateWithOptions:]
只有当我的应用程序是最前面的进程时才会起作用。
如果我[NSApp activateIgnoringOtherApps:YES];
在调用之前添加[NSRunningApplication activateWithOptions:]
,它始终按预期工作,但是,由于仅激活我的应用程序然后激活不同的应用程序,菜单栏会闪烁。于是问题就变成了:
[NSRunningApplication activateWithOptions:]
当我的应用程序不是最前面的应用程序时,有什么方法可以开始工作吗?并且activateWithOptions:
应该以这种方式工作?