iPhone Duo's fold, for the MacBook lid you already have.
iFold reads the hinge angle from your MacBook's built-in lid sensor and bends your live desktop as the lid comes down: the picture tilts away in perspective (so it "holds its place" in space), blurs and shades, then springs flat with a soft click when you open the lid past the clear angle.
- Apple silicon MacBook with a lid-angle sensor (M2 Air and later, 14"/16" Pro).
- macOS 14 Sonoma or later.
- Screen Recording permission — the desktop is captured with ScreenCaptureKit. Frames never leave the GPU; nothing is saved or uploaded.
⬇ Download ifold-mac.dmg (latest release · all releases · website)
-
Open the DMG and drag iFold Mac into Applications.
-
Launch it. macOS will say it "could not verify that iFold Mac is free of malware" — the app is signed but not yet notarized (that needs a paid Apple Developer ID; the build is reproducible from source if you'd rather not trust a binary). Click Done, open System Settings → Privacy & Security, scroll to the bottom and click Open Anyway, then Open.
Terminal alternative that skips the dialog:
xattr -d com.apple.quarantine "/Applications/iFold Mac.app" -
iFold Mac asks for Screen Recording. Enable it under System Settings → Privacy & Security → Screen & System Audio Recording, then click Relaunch in the iFold Mac window.
-
Tilt the lid down a little. That's it — iFold Mac lives in the menu bar (laptop icon).
Verify the download if you like: shasum -a 256 ifold-mac.dmg should match SHA256SUMS
on the release page.
iFold Mac is free and open source. If it makes closing your Mac a little nicer, sponsor the project on GitHub. Sponsorship pays for the Apple Developer membership that lets releases be notarized — which is exactly what makes the Open Anyway step above disappear — and for the time to keep shipping.
Needs Xcode 15+ (or the Command Line Tools with a Swift 5.9 toolchain).
git clone https://github.com/maheshj01/ifold-mac.git
cd ifold-mac
./build.sh --run # build, assemble "build/iFold Mac.app", launch
./build.sh --install # same, then copy to /Applicationsbuild.sh signs with whatever Apple identity is in your keychain (so the Screen
Recording grant survives rebuilds) and falls back to an ad-hoc signature.
On first launch grant Screen Recording as described above, then relaunch.
iFold Mac lives in the menu bar (laptop icon). The popover shows the live hinge angle and lets you tune everything about the fold:
| Control | What it does |
|---|---|
| Style | The motion itself — see below. |
| Follow lid / Manual | Track the real hinge, or drag the angle yourself to preview. |
| Clears at | Hinge angle at which the desktop is flat again (default 100°). |
| Perspective | How far the picture leans per degree of lid travel. |
| Bend | 0 = rigid plank hinged at the bottom, 100 = flat at the hinge, curling toward the top. |
| Motion blur | Directional smear while the lid is moving; crisp once it settles. |
| Frost | Static blur that builds as the lid comes down. |
| Shade | Lighting falloff on the parts of the sheet facing away. |
| Silk / Shade / Frost | Looks: presets for the sliders above, on whichever style is chosen. |
Seven motions, all riding the same spring, motion blur and frost:
| Style | As the lid comes down… |
|---|---|
| Fold | The desktop leans away from the hinge, curling toward the top. The default. |
| Curl | The top edge rolls over and away, like a page curling toward the hinge. |
| Genie | The desktop is drawn down into the hinge, the way windows minimize into the Dock. |
| Notch | The desktop is pulled up into the notch — the real one, measured from the display — and comes back out when you open the lid. |
| Cube | The desktop is one face of a cube turning with the lid; the underside swings into view. |
| Scale | The desktop shrinks toward the hinge and settles into the dark. |
| Fade | The desktop dims and drains of colour, like a display drifting to sleep. |
Click anywhere on the bent desktop to pause until the lid opens again.
Can't find the icon? On a notched MacBook, macOS silently hides menu bar items that don't fit beside the notch. Open iFold Mac again (Spotlight, Launchpad, or double-click it in Applications) and the settings window appears — it has everything the popover has, including Quit.
- On device, in GPU memory only. Captured frames are IOSurfaces handed straight to Core Animation. Nothing is encoded, written to disk, or sent anywhere — the binary links no networking framework and opens no sockets.
- No entitlements, hardened runtime. Not sandboxed (the lid sensor and ScreenCaptureKit need that), but no Input Monitoring, Accessibility, camera, microphone, or file-system grants are requested. The HID match is pinned to the lid sensor (VID 0x05AC / PID 0x8104 / Sensor·Orientation); it cannot see keyboard or trackpad traffic.
- Frames are dropped on sleep, display sleep, screen lock and fast user switch, and the capture stream stops. The overlay never outlives the session it was captured in.
- The overlay only captures your own display, with iFold Mac's own windows
excluded, and it is itself invisible to other screen recorders
(
sharingType = .none). - Developer hooks are compiled out.
./build.sh --debug-toolsadds Darwin-notification-triggered screenshot and demo-motion hooks; they are intentionally absent from normal builds because it would let any local process borrow iFold Mac's Screen Recording grant. - Distribution note. Release DMGs are currently signed with an Apple
Development identity, not notarized — hence the one-time Open Anyway step.
release.shnotarizes and staples automatically as soon as a Developer ID certificate and anotarytoolprofile are present.
Known limitation: while the desktop is bent, the overlay sits above every other window (like Bendy). A system dialog that appears at that moment is underneath it until you click (pause) or open the lid.
Measured on an M4 MacBook Pro 14":
| State | iFold Mac CPU | RSS | Notes |
|---|---|---|---|
| Idle, lid parked | ~1.5% | ~70 MB (mostly shared framework pages) | 30 Hz sensor poll + 20 Hz display link; capture stopped; no measurable WindowServer load |
| Bending | ~30% | +~2 MB | ScreenCaptureKit at 60 fps full Retina; frames live in ~5 IOSurfaces (GPU); WindowServer +~10–15% for the composite |
The capture stream starts only when the lid is actually closing toward the threshold (startup ≈ 130 ms) and stops 3 s after the desktop clears, so a lid resting at a normal working angle costs nothing beyond the idle poll.
Logs go to the unified log under subsystem com.wml.ifold-mac
(note: log is a zsh builtin, use the full path):
/usr/bin/log stream --predicate 'subsystem == "com.wml.ifold-mac"' --infoTwo developer hooks exist for working on the renderer and recording demo footage. They are compiled out of normal builds (see Privacy & security posture) and only present when you build with:
./build.sh --debug-tools --runThen, with that build running:
# Screenshot of the built-in display *including* iFold Mac's own overlay
defaults write com.wml.ifold-mac snapshotPath ~/Desktop/ifold.png && notifyutil -p com.wml.ifold-mac.snapshot
# Scripted close / pause / flick-open lid path in Manual mode, visible to screen recorders
notifyutil -p com.wml.ifold-mac.demoPublishing a DMG is one command, but three files describe the release; keep them in step:
- Version — bump
CFBundleShortVersionString(andCFBundleVersion) inResources/Info.plist. Tags are immutable, so a version that's already been tagged can't be re-published. - Notes — write the What's new for this version in
RELEASE_NOTES.md;release.shputs it at the top of the GitHub release, above the standard install steps and checksum. - Site — update the version/size line in the download dialog in
site/dist/index.html(the DMG size is printed byrelease.sh; ~1.2 MB today).
Commit and push those, then:
./release.sh --publishBuilds, signs, lays out dist/ifold-mac.dmg, tags v<version>, pushes the tag, creates the GitHub
release (or replaces the assets if the release for this commit already exists), uploads
ifold-mac.dmg + SHA256SUMS, then downloads the DMG back through the public
releases/latest/download/ifold-mac.dmg link and fails unless the checksum matches.
It refuses to run on a dirty tree, an unpushed HEAD, or a version already tagged at another
commit. Add --dry-run to see the steps without tagging or uploading.
Any time, confirm what GitHub is actually serving (and that it matches its own checksum):
./release.sh --checkThe asset is always named ifold-mac.dmg, so the download links in this README and on the
website keep working across releases. If a Developer ID Application identity and a
notarytool keychain profile named ifold-mac exist, the same command notarizes and staples
both the app and the DMG, and the Gatekeeper Open Anyway step disappears for users.
What never ships. Normal builds contain no screenshot, demo or recording code: the developer
hooks live behind --debug-tools (see Privacy & security posture), and build.sh refuses to
assemble a normal build whose binary contains them. site/record-demo.sh, which records the
website's style clips, uses a --debug-tools build and is tooling for the site, not a feature of
the app.
LidAngleSensor— reads HID feature report #1 from the Apple sensor hub (VID 0x05AC, PID 0x8104, Sensor/Orientation usage). Public IOKit only.ScreenCapturer— ScreenCaptureKit stream of the built-in display, excluding iFold Mac's own windows.FoldView— the desktop as a flexible sheet: horizontal strips (8–64 depending on the style) (IOSurface contents +contentsRect) chained end to end and rotated progressively so the surface curves away from the hinge, under a perspectivesublayerTransform. Each strip carries a Lambert-style shade gradient and a specular sheen band. ACIMotionBluron the container smears the projected sheet in screen space while it moves. Zero copies — frames are IOSurfaces set straight as layer contents.FoldController— idle → engaged → releasing state machine, driven by the display'sCADisplayLink(120 Hz on ProMotion). The lean follows the hinge through a second-order spring (a touch of inertia, a whisper of overshoot); motion-blur radius is derived from the spring's velocity with a fast attack and slow release so the picture smears the instant it moves and resolves as it settles. Pre-warms the capture stream as the lid nears the threshold so the bend starts without a black flash; releases through the same spring and stops the stream once flat.
