App Nap, undead and nascent apps in Ventura

If you’d like to think that apps are either running or not, this may come as a surprise, but apps can exist in at least five distinct states in macOS. This article tries to explain those, and look at difficult app behaviours involving App Nap and what I refer to as undead apps, in Ventura.

To help confuse you, I have two little purposeless apps, both called StateTest2. One behaves like many of Apple’s apps and becomes undead when you leave it alone, the other doesn’t. You can download the pair of apps from here: StateTest2f

They’re both notarised, require macOS Ventura 13.0 or later, and to distinguish them one is called StateTest2n, and the other StateTest2q (for quit). The two apps don’t do anything useful, other than display document windows, and they’re identical in every other respect apart from one: StateTest2q sets its ProcessInfo variable automaticTerminationSupportEnabled to true, while StateTest2n leaves it set to the default, which clearly isn’t true! According to Apple’s documentation, setting that to true enables support for “automatic termination”. In other words, it allows it to become undead. You’ll also come across the NSSupportsAutomaticTermination setting in an app’s Info.plist, which has the same effect.

App states

I first explored what was going on over five years ago, and discovered that apps could then have four different states. Just over two years ago, Felix Schwarz discovered a fifth state, bringing the list to:

  1. running and not napping: these are apps which are still open, and have windows open, even if they’re not at the front;
  2. running in App Nap, and still fully accessible: these are open even though they may have no open windows, and are still active in the Dock;
  3. running but suspended, in App Nap, and hidden from normal user access: undead, which macOS may terminate whenever it chooses;
  4. started loading but halted, which happens when your Mac starts up with apps that were napping in state 2 with no windows open when it was shut down or restarted. Although macOS starts to load these apps, it halts after loading just part of them, so they may not respond to events, making them nascent.
  5. Not running at all.

The user only controls states 1 and 5. All apps will be put into App Nap (state 2) unless they’re active, and the old NSAppSleepDisabled setting in an app’s Info.plist is now ignored, and has been since Sierra. It’s also worth noting that Intel-only apps being run through Rosetta 2 translation on Apple silicon can persist for many hours in state 3 (undead).

Undead apps almost vanish from the human interface, and you can only quit them after ‘opening’ that app again, or in Activity Monitor. They do, though, remain listed in the Finder’s Force Quit Applications dialog, where you can clean them up when you wish.

State demonstration

Once you have downloaded and unZipped the folder containing the two apps, move each to your Applications folder, or another location from where you’re going run them. Open each in turn to clear its quarantine flag, then quit them.

Start by opening both apps and leaving their single windows open. Open Activity Monitor, select its Energy view, and set it up to show recent apps only ordered by App Nap. Put the two StateTest apps into the background and leave them a few minutes, and they will both go into App Nap, state 2.

Bring each to the front in turn by clicking on its icon in the Dock, close its only window, and put it into the background again. While StateTest2n returns to state 2, and is shown in the Dock as still running, StateTest2q appears to quit in the Dock, although Activity Monitor shows both apps still running in App Nap. StateTest2q has now entered state 3, it’s undead.

Quit all other open apps apart from the two StateTest apps and Activity Monitor, then restart your Mac.

Once it has restarted, you should see in Activity Monitor that StateTest2n has opened straight into App Nap, with no window open. This time, though, instead of taking about 12.5 MB of memory, it only uses 6 MB until you switch to it, when it opens a new window and its memory rises to 12.5 MB. You can confirm that StateTest2n is initially in state 4, nascent, by getting information in Activity Monitor and viewing its list of open files, which is far shorter when it’s in state 4 or nascent.

Relevance

For users, the differences between states 1 and 2 aren’t significant. App Nap is largely transparent, and the user retains full access to an app which is simply napping.

Undead apps (state 3) are more of a problem, as macOS is in control of them, not the user. For small apps that load briskly, like TextEdit and Preview, there’s little difference between states 1, 2, 3 or 5, except that undead apps that aren’t already installed in the Dock can’t be woken up from there, as their icon may have been removed even though they’re really still running in App Nap.

Larger apps like Pages and Xcode are more of a problem. When undead, returning the app to state 1 is almost instant, but a few minutes later, should macOS decide to quit it, the app would have to be launched from scratch, causing a delay of several seconds. To maintain instant access to an app that becomes undead, you have to leave one of its windows open, only adding to screen clutter.

Originally state 4, nascent, only loaded a tiny 4 KB stub of the app; while this does appear to have improved over the last couple of years, it’s not clear whether that has restored the app’s ability to respond to events. There’s also the contradiction that undead apps, shown as inactive in the Dock, are instantly fully functional, while nascent apps, shown in the Dock as open, have been halted before they have loaded fully.

Human interface

Whatever the performance or engineering advantages to this multiplicity of app states, they remain thoroughly confusing for the user, who just sees conflicting information in the interface. This is most apparent when StateTest2n is in state 2 with all windows closed, but still marked as running in the Dock. Yet when StateTest2q is treated identically by the user, according to the Dock the app quits without user approval, but remains visible in the Force Quit dialog and Activity Monitor.

undead1

It would make more sense for the Dock to show undead apps as still being open until macOS decides to quit them. Surely the user should be allowed to decide whether an app is quit when there are no pressures on computer resources like memory. Instead, to trick macOS into keeping an app like Xcode open, I have to leave one of its windows open, to prevent it being made undead and quit at a time determined by macOS not the user.