ATMOS

Taking longer than usual — check your network connection.

AtmosAtmos
LibraryBlogPricing
Sign inDownload
Journal

How Atmos Keeps the Real Cursor Hidden

A deeper look at the layered cursor-hiding system that lets Atmos replace the macOS pointer without constant flicker or lag.

GuideCursorDocumentationPermissionsFeatures

If you use cursor skins in Atmos, one of the most important parts of the feature is also one of the least visible. The app is not just drawing a custom cursor. It also has to keep the real macOS cursor from leaking through.

That sounds simple at first, but it is actually a reliability problem. The system cursor can come back during mouse movement, style changes, app switches, Space changes, and display wake events. Atmos handles that with a layered hiding strategy instead of relying on a single call.

This guide explains how that works.

Replacing the cursor is a two-part job

Atmos cursor skins only feel convincing if two things happen at the same time:

  • the custom cursor overlay follows the mouse smoothly
  • the real system cursor stays hidden

If the app only drew a custom image without hiding the original cursor, users would see both at once. If it hid the cursor once and stopped there, the system cursor could come back during later desktop events.

That is why Atmos treats cursor hiding as an ongoing system, not a one-time setup step.

Atmos hides the system cursor once, then maintains it

When cursor skins activate, Atmos does perform a real cursor hide call. That gives it a baseline hidden state and sets up the internal balance it will later unwind when the feature turns off.

But it does not repeat that same expensive hide call on every mouse move. Doing that constantly would create unnecessary overhead and hurt performance.

Instead, Atmos separates the job into two layers:

  • a persistent hidden state
  • cheap ongoing obscuring during movement and ticks

That split is a big part of why the feature can feel responsive without turning into a CPU-heavy hack.

Mouse movement uses a cheaper obscuring path

After the initial hide, Atmos installs a session event tap for mouse movement and drag events. On each matching event, it calls a lighter obscuring path that keeps the cursor hidden at the system level without repeatedly stacking full hide calls.

This is important because cursor movement is constant. The app needs something efficient enough to run all the time.

If the event tap is unavailable, Atmos falls back to a global mouse monitor that still obscures the cursor on movement. That fallback does not provide the same level of control, but it helps maintain the illusion even when full event-tap behavior is not available.

Atmos still hides on every tick when needed

Atmos does not rely only on movement events. The cursor engine also runs a regular tick, and during that tick it obscures the cursor again so the real pointer does not leak through while the mouse is stationary.

That hidden behavior matters more than it sounds. Without it, the custom cursor could look correct while moving but briefly reveal the real pointer during quiet moments between events.

So the system effectively covers both cases:

  • movement-driven re-obscuring
  • idle-time re-obscuring

Together, those make the cursor replacement feel much more stable.

Why Accessibility matters

The best hiding path uses a system event tap, and on macOS that depends on Accessibility trust. Atmos checks whether Accessibility access is available and exposes that state in the app when cursor skins are enabled.

If permission is missing, Atmos can still fall back in some situations, but the full cursor replacement experience is designed around that trusted event path.

This is why the permission prompt is not just a generic system requirement. It directly affects how reliably Atmos can keep the original cursor suppressed while the custom skin is active.

Space switches, app activation, and wake events can reveal the cursor

One of the trickiest problems is that the system cursor can return even when the user has not moved the mouse.

Atmos watches for cases like:

  • switching Spaces
  • activating another app
  • the app resigning active state
  • displays waking from sleep

When one of those happens, Atmos synthesizes a tiny mouse nudge so the hiding pipeline fires again. That gives the app a way to re-hide the cursor even when there is no real pointer movement to trigger the event tap naturally.

This is one of the most important hidden behaviors in the cursor system. It is the difference between a feature that works in demos and one that survives normal desktop use.

Cursor style changes can break the hide balance too

macOS does not always keep the same underlying cursor object. When the system changes cursor style, it may internally reveal the cursor again.

Atmos explicitly watches for that. During its tick, it compares the current system cursor object against the last one it saw. If the cursor object changed while Atmos still expects the cursor to be hidden, it hides the cursor again and updates its internal hide counter.

That means Atmos is not just hiding a pointer image. It is also tracking the system's cursor state closely enough to repair itself when macOS swaps cursor objects under the hood.

The hide and show counts are balanced carefully

Full cursor hide and show calls are reference-counted behavior. If an app hides the cursor multiple times, it has to show it the same number of times later.

Atmos keeps track of extra re-hide operations so it can unwind them correctly when cursor skins turn off. That prevents the app from leaving the system cursor hidden longer than it should.

This is a subtle engineering detail, but it is essential. A cursor replacement system is only trustworthy if it cleans up after itself.

Hidden behaviors worth knowing

Here are a few easy-to-miss details behind the feature:

  • Atmos does a real hide once, then uses lighter obscuring continuously
  • the engine keeps obscuring the cursor even when the mouse is not moving
  • app switches and Space switches trigger a synthetic re-hide nudge
  • cursor object changes can cause a re-hide to keep the hide count balanced
  • the engine falls back gracefully when the preferred event tap path is unavailable

These are not things most users ever need to configure, but they are a big reason the cursor system feels polished.

What this means in practice

When Atmos cursor skins work well, the result feels simple: you enable a skin and the normal pointer disappears. Under the hood, though, the app is constantly maintaining that illusion across system events, idle time, permission differences, and cursor-style changes.

That is why the feature feels more robust than a basic overlay. Atmos is not just drawing a custom pointer. It is actively managing the conditions that let the real one stay out of sight.

Atmos Journal

More posts, product updates, and deep dives from the team.

Browse the journal