How macOS decides which app is frontmost, and why it matters

· 6 min read

Any tool that records where your day went rests on a single question the system answers continuously: which application is in front right now. It is worth understanding how that answer is produced, because its limits are the limits of every automatic time record you will ever read.

The mechanism

macOS maintains a notion of the active or frontmost application: the one whose menus appear in the menu bar and whose window receives keystrokes. Exactly one application holds that status at a time.

You can ask for it directly:

osascript -e 'tell application "System Events" to name of first application process whose frontmost is true'

Run that from Terminal and it prints Terminal, because Terminal was in front when the command ran. Switch to another app and run it again, and you get that app’s name.

Applications can also be told when the frontmost app changes, rather than repeatedly asking. The system posts a notification at the moment of the switch. This matters for battery: an app that waits for notifications does nothing between switches, whereas one that polls every second is working continuously to learn nothing. It is the difference between a tracker that costs nothing to run and one you notice.

What the system knows, and what it does not

The frontmost application is a name and a process. That is the whole of it.

It does not include what is inside the window. Not the document, not the URL, not the text on screen. An app that knows the browser is in front does not know which page, and an app that knows the editor is in front does not know which file.

Getting that detail requires more: window titles need Accessibility permission, page contents need Screen Recording permission or a browser extension. Those are separate, and macOS asks explicitly because they are genuinely intrusive. What Mac apps can see, permission by permission goes through what each grant allows.

So there is a real boundary here. App-level tracking needs no permissions because the frontmost app name is not considered sensitive. Everything more detailed does.

The four things this cannot know

Worth being explicit, because these are the honest limits of any app-level record.

Which window. Two documents in the same editor are one line in the record. Six hours in a browser is six hours in a browser, whether that was research or football scores.

Whether you were there. The frontmost application does not change when you leave the desk. A document open while you were at lunch reads as a document you were working on, unless the tracker also watches for idleness.

Whether the work was work. No system-level signal distinguishes a client email from a personal one in the same mail application.

What happened on another machine. Each Mac answers this question for itself. Two machines produce two records. Tracking time across two Macs covers that.

Idleness, which is the one worth handling

The second limit above is the one that most distorts a day, and it is addressable without any additional permission, because the system exposes how long since the last input:

ioreg -c IOHIDSystem | grep HIDIdleTime

The figure is in nanoseconds since the last keyboard or mouse event. A tracker that watches this can stop counting after a few minutes of no input, which is the difference between a record that says nine hours and one that says the six you actually spent at the machine.

It is a heuristic rather than a truth. Reading on screen without touching anything looks identical to being absent. Anyone who reads long documents will find time trimmed that they genuinely spent working. That is a trade with no correct answer, only a choice about which direction to be wrong in.

Why the limits are the point

It is tempting to read all this as a list of deficiencies to be fixed with more permissions. The opposite case is worth putting.

A record built on application names alone cannot leak the contents of your work, because it never had them. There is no document title to appear in a report, no URL in a log, nothing to be exposed if the data is read by someone else. The record is coarse, and coarseness is the privacy property.

Punchcard uses exactly this signal and nothing more: the frontmost application’s name, by notification rather than polling, with idle time subtracted. No macOS permissions are requested, because none are needed for that. At the closing time you set, it prints a receipt of the day, one line per app.

What it will not tell you is which browser tab, which document, or which client. It has no projects, tags or timers. That is a genuine limitation, and if you need billable hours broken down by client you need something else. For seeing the shape of a day, application names are enough, and they cost nothing to collect. What automatic time tracking can and cannot know sets that out in full.

Questions

Can an app see the frontmost application without permission? Yes. The name of the active application is not treated as private, in the same way that the list of running applications is not. Window titles and contents are, and require explicit grants.

Does this work when the Mac is locked? Input stops, so a tracker watching idle time stops counting. The frontmost application does not change while the screen is locked.

What happens with full-screen apps and Spaces? Switching Spaces changes the frontmost application if the new Space contains a different app, and the notification fires normally. Nothing special is required.

Does a background app that shows a window become frontmost? Not unless it takes focus. An app can display a window without activating; the frontmost application only changes when focus moves.