Hello all,
Recently I observed a strange behaviour on macOS. Some apps with UI, after you quit them (right click on the Dock, select Quit or select Quit from the menubar), the apps are not actually quitting immediately, but in a few seconds (including in Activity Monitor the apps are staying alive). Also, if you open the apps again fast, the same PID is kept.
Not all apps do this, some of them, for example WhatsApp. I'm not referring to closing all windows, but explicitly quitting.
This was not the case in the past. Is there any reason for this? Is some kind of optimisation I'm not aware of?
The actual issue is that in a Swift developed app events like NSWorkspace.didLaunchApplicationNotification or NSWorkspace.didTerminateApplicationNotification are not triggered.
Is there any way to tell if an app was closed, even if macOS still keeps it around for a few more seconds?
Thank you.
Recently I observed a strange behaviour on macOS. Some apps with UI, after you quit them (right click on the Dock, select Quit or select Quit from the menubar), the apps are not actually quitting immediately, but in a few seconds (including in Activity Monitor the apps are staying alive). Also, if you open the apps again fast, the same PID is kept. Not all apps do this, some of them, for example WhatsApp. I'm not referring to closing all windows, but explicitly quitting.
Jus to clarify, "Quitting" a macOS applications is in fact an "optional" action and always has been. The app is "asked" to quit, but is not in ANY way obligated to do so. There are multiple "routes" used to implement this behavior, but the original/basic code path is NSApplicationDelegate.applicationShouldTerminate. That method is called when "Quit" is called and if the application returns "NSTerminateCancel" or "NSTerminateLater", then the applications does not quit.
Note that neither NSTerminateCancel nor NSTerminateLater require the app to actually terminate "soon" or in any particular time frame.
This was not the case in the past.
The system has always worked this way and you've likely seen it occur many, many times. Every time you see a "Are you sure you want to Quit?" dialog or a "This document has unsaved changes, do you want to save?" dialog, the sequence above or one of the other variations was what as actually going on.
In terms of what you're describing here:
the apps are not actually quitting immediately, but in a few seconds (including in Activity Monitor the apps are staying alive). Also, if you open the apps again fast, the same PID is kept.
I don't think the system itself is doing this, but I can see how a macOS app could "appear" to quit without actually quitting. The basic sequence would be this:
-
Receive NSApplicationDelegate.applicationShouldTerminate and return NSTerminateCancel/NSTerminateLater.
-
Use NSApplication.setActivationPolicy and "NSApplicationActivationPolicyAccessory" or "NSApplicationActivationPolicyProhibited" to remove yourself from the dock, app switcher, etc.
-
Finish whatever work you were doing, then exit().
Finally, this behavior:
Also, if you open the apps again fast, the same PID is kept.
- If you receive "NSApplicationDelegate.applicationShouldHandleReopen...", then stop your exit sequence and become visible again by using NSApplication.setActivationPolicy and "NSApplicationActivationPolicyRegular"
The actual issue is that in a Swift developed app events like NSWorkspace.didLaunchApplicationNotification or NSWorkspace.didTerminateApplicationNotification are not triggered.
Swift doesn't matter at all here. As the sequence above lays out, the app did not launch or terminate, so neither event would have occurred.
Is there any way to tell if an app was closed, even if macOS still keeps it around for a few more seconds?
Again, I think the app itself is doing this, not macOS. In any case, I believe you could see this happening using NSRunningApplication.activationPolicy. However, be aware that inferring "intention" here will be tricky. You'll see the activationPolicy change, but you won't have any way to know if that occurred because the app received "quit" or because of some other factor/choice.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware