Imperator CRT Overlay
A transparent Metal overlay with scanlines, tube-corner shadow, flicker, RGB fringing and tape noise that ignores the mouse, with presets and per-display switches.
README.md
// Overview
A macOS menu bar app that lays a live CRT and VHS effect over your screen. The overlay is a transparent window on top of everything else: scanlines, darkened tube corners, vignette, flicker, RGB fringing, tape noise and jitter. It is rendered in Metal, at 30fps while something in it moves, and ignores the mouse, so you keep working underneath it.
Everything lives in the menu bar. There is no Dock icon and no window to manage. Ten effect sliders plus a master intensity, built-in presets with your own saved on top, and a switch per display so one screen can stay clean. The overlay holds through Mission Control, Spaces and Show Desktop.
Requires macOS 13 or later, Apple silicon. Built and tested on macOS 27 only, older versions are expected to work but have not been verified.
Install at your own risk. The app is not notarized and carries no Apple Developer signature, so macOS cannot vouch for it. It is provided as is, with no warranty, under the MIT license.
// Install
Download the zip from
Releases,
unpack it, and drag Imperator CRT Overlay.app into /Applications.
The app is ad-hoc signed, so Gatekeeper blocks the first launch. Right-click the app and choose Open, then Open again in the dialog. Or clear the quarantine flag yourself:
xattr -dr com.apple.quarantine "/Applications/Imperator CRT Overlay.app"// Permissions
None. The overlay is an ordinary borderless window that passes mouse events
through, so the app needs no Accessibility, Screen Recording or Automation
grant. Open at Login uses SMAppService, which registers the app with the
system without a permission prompt.
// Use
Click the menu bar icon to open the panel. The header switch turns the overlay on and off, and Intensity sets the master strength for every effect below it.
| Control | What it does |
|---|---|
| Scanlines | Horizontal line darkness |
| Vignette | Corner falloff |
| Flicker | Brightness wobble over time |
| Noise | Static grain |
| Curvature | Darkens the corners and edges, the shadow of a curved tube. The image itself is not warped |
| RGB Dark | Shadow mask darkening between phosphor stripes |
| RGB Color | Colour separation across the stripes |
| VHS | Tape smear and chroma bleed |
| Static | Horizontal jump and tearing |
| Size | Scale of the pattern: scanline pitch, the RGB grid, the VHS bands and the static blocks |
| Screens | One switch per display. A display the app has not seen before starts on |
| Presets | Your own presets and the Save button on top, the built-in looks below. A preset holds every slider, Intensity included |
Settings survive a restart, except the header switch: the overlay always starts on. Opening the app again from Finder or Spotlight opens the panel, which is the way back to the settings if the menu bar icon is hidden.
// Build
No Xcode project. The app is compiled with swiftc from a Makefile:
make buildmake runmake cleanThe build stamps the binary with the current SDK while keeping the deployment
target at macOS 13. AppKit picks which generation of a control to draw from the
sdk field in LC_BUILD_VERSION, not from the macOS it is running on, so a
binary stamped with an old SDK draws old switches forever. The minos half is
what lets the app launch below macOS 27 at all. Ad-hoc codesigning runs as part
of make build and is not optional: without it Gatekeeper refuses the bundle.
// Release
make dist VERSION=x.y.zBuilds the app, stamps the version into the bundle, re-signs it and writes the zip. It touches nothing in git.
make release VERSION=x.y.zBumps Info.plist, commits, tags vx.y.z, pushes, and publishes the GitHub
release with the zip attached. It refuses to run on a dirty working tree.
// Implementation note
Seven Swift files, no external dependencies. The Metal shader is an inline
string, and its Uniforms struct must stay field-for-field in sync with the
Swift one.
The menu bar panel is drawn by MenuBarPanel.swift, not by NSPopover.
NSPopover draws its own frame and exposes no radius to set, and neither frame
it draws is the one macOS uses in the menu bar. So the app draws the surface
itself: a borderless NSPanel over an NSVisualEffectView on the .popover
material, with a corner of 17.5pt. No arrow and no open or close animation,
because macOS 27's own menu bar panels have neither.
// Known limits
Apple silicon only. While an effect moves the overlay redraws at a fixed 30fps, not at the display's refresh rate. The panel has no height cap, so with both sections open and many saved presets it can run past the bottom of a small display. Effect parameters are global; per-screen settings cover on and off, nothing more. Not notarized, so every update needs the Gatekeeper right-click again.
// Third-party
None. AppKit, SwiftUI, Metal, MetalKit, QuartzCore and ServiceManagement only.