macOS:有什么方法可以知道用户何时尝试通过其Dock图标退出应用程序?

时间:2019-07-16 19:13:57

标签: macos cocoa exit nsapplication nsapplication-delegate

可可应用程序是否有任何方法可以检测到用户何时尝试通过其Dock菜单而不是其他方法退出它?

通常,可以使用应用程序委托的applicationShouldTerminate:方法捕获并响应退出事件。但是,此方法似乎无法区分来自应用程序主菜单,其Dock图标,来自Apple事件的退出请求,还是来自其他任何退出应用程序的常规方法。我很好奇是否有办法确切地知道用户如何尝试退出该应用程序。

1 个答案:

答案 0 :(得分:3)

实际上,应用程序可以通过检查是否正在处理当前的AppleEvent来了解退出原因,如果是,则检查是否是退出事件以及是否发送了Dock它。 (请参见this thread,讨论如何判断是否由于系统正在注销或关闭而退出应用程序。)

以下是方法的示例,当通过应用程序委托的applicationShouldTerminate:方法调用该方法时,如果通过Dock退出应用程序,则该方法将返回true:

- (bool)isAppQuittingViaDock
    NSAppleEventDescriptor *appleEvent = [[NSAppleEventManager sharedAppleEventManager] currentAppleEvent];

    if (!appleEvent) {
        // No Apple event, so the app is not being quit by the Dock.
        return false;
    }

    if ([appleEvent eventClass] != kCoreEventClass || [appleEvent eventID] != kAEQuitApplication) {
        // Not a 'quit' event
        return false;
    }

    NSAppleEventDescriptor *reason = [appleEvent attributeDescriptorForKeyword:kAEQuitReason];  

    if (reason) {
        // If there is a reason for this 'quit' Apple event (such as the current user is logging out)
        // then it didn't occur because the user quit the app through the Dock.
        return false;
    }

    pid_t senderPID = [[appleEvent attributeDescriptorForKeyword:keySenderPIDAttr] int32Value];

    if (senderPID == 0) {
        return false;
    }

    NSRunningApplication *sender = [NSRunningApplication runningApplicationWithProcessIdentifier:senderPID];

    if (!sender) {
        return false;
    }

    return [@"com.apple.dock" isEqualToString:[sender bundleIdentifier]];
}