Case study · 2026 · Personal daily driver

NotchPal

A macOS notch companion in Swift/SwiftUI — Now Playing, a file shelf, a mirror, and a system HUD living around the MacBook notch. Built without Xcode.

Role

Solo developer

Type

macOS app · Swift & SwiftUI

Year

2026

Links

SwiftSwiftUIAppKitCoreAudioIOKitAVFoundationMediaRemote
Expanded notch shelf — Now Playing, files, and quick tools
01 / 03

Expanded notch shelf — Now Playing, files, and quick tools

Overview

The MacBook notch is dead space with prime real estate. NotchPal turns it into a control surface: hover and it blooms into a panel with Now Playing controls, a drag-and-drop file shelf, a camera mirror, timers with a countdown ring traced around the notch itself plus a battery readout in the corner.

It's also a systems project: no Xcode (Swift Package Manager and command-line tools only), private-framework spelunking for media metadata, and an NSPanel that has to live where AppKit insists windows can't.

0

Xcode involved

3

Tabs — Home, Shelf, Mirror

26px

HUD that grows below the notch

100%

Swift + SwiftUI

The problem

Apps like NotchNook proved the notch can be useful but I wanted mine: my animations, my features, my rules, and a codebase I understand down to the window server.

The hard parts are all systems problems. macOS 15.4+ returns empty Now Playing data to third-party binaries; AppKit actively pushes windows out of the menu-bar zone; and the volume HUD needed to appear without any of the permissions a global event tap requires.

What I built

A borderless panel over the notch, and everything that lives inside it:

Now Playing

Artwork, controls, progress — via a MediaRemote helper, with AppleScript fallback for Music/Spotify

Shelf & Mirror

2

A drag-and-drop file tray that follows you between apps, and a camera mirror tab

System HUD

26px

Volume and brightness changes stretch the notch downward with an animated level bar

Timer & widgets

A countdown ring traced around the notch silhouette, presets, and a battery badge in the corner

The systems work

Beating the MediaRemote lockout

macOS 15.4+ answers MediaRemote queries only for Apple-signed processes — so a helper runs via /usr/bin/swift (an Apple-signed interpreter), streams now-playing JSON over stdout, and takes play/pause commands on stdin.

A window where windows can't go

The panel overrides constrainFrameRect to defeat AppKit's menu-bar eviction, and sets its level above the main menu — ordered carefully, because isFloatingPanel silently resets window level.

Volume HUD with zero permissions

A CoreAudio property listener on the default output device catches every volume/mute change — no event tap, no Accessibility prompt — and brightness polls a private DisplayServices getter that fails silently if Apple removes it.

Choreographed, not just animated

Open: window grows silently, then the shape springs into it, then content fades in. Close: exact reverse. Resizing and animating in the same pass makes SwiftUI pop instead of spring — sequencing is the feature.

Technical challenges

01

No Xcode, on purpose

The whole app builds with swift build and a shell script that assembles and ad-hoc signs the .app bundle — which meant learning exactly what Xcode does for you, then doing it by hand.

02

Windows that resize without flinching

The collapsed pill grows wings for media, stretches down for the HUD, and blooms into a panel — each needs the NSWindow resized at the right moment relative to the SwiftUI animation, or the whole illusion collapses.

03

Graceful private-API failure

MediaRemote and DisplayServices are private frameworks that can vanish any release. Every private call sits behind a fallback (AppleScript polling, feature disabling) so the app degrades instead of crashing.

Outcome

NotchPal runs on my Mac every day music control, file shelf, volume HUD, and timers all living in the notch, with the exact feel I wanted because every spring constant is mine.

It's the project that took me from web developer to systems developer: window servers, CoreAudio listeners, process signing, and the discipline of building against APIs that owe you nothing.

What's next

Clipboard history tabCalendar peekPublic beta build