Turn your XREAL glasses into a head-tracked, multi-monitor spatial workspace on macOS. Create as
many virtual displays as you like, arrange them in the space around you, and drag your Mac windows
onto them — all rendered into the glasses with low-latency head tracking.
Requirements: a supported pair of XREAL glasses connected over USB-C DisplayPort, and a Mac
(Apple Silicon or Intel) running macOS 14 (Sonoma) or later.
| Glasses | Head tracking | Notes |
|---|---|---|
| XREAL Air (original) | 3DoF (IMU over HID) | Same Air path as the Air 2, incl. host brightness control |
| XREAL Air 2 | 3DoF (IMU over HID) | Full support, incl. host brightness control |
| XREAL Air 2 Pro | 3DoF (IMU over HID) | Full support, incl. host brightness control |
| XREAL One | 3DoF (IMU over USB-ethernet) | Enable Ethernet in the glasses’ menu; use flat Follow mode — see below |
| XREAL One Pro | 3DoF (IMU over USB-ethernet) | As One, plus automatic mount-tilt correction; the Eye accessory’s 6DoF isn’t exposed to the host, so tracking stays 3DoF |
XREAL One / One Pro
The One series works, with three things to know (their onboard X1 chip behaves differently from the
Air):
- Head tracking comes over the glasses’ built-in USB-ethernet link, so enable Ethernet in
the glasses’ side/developer menu (on by default on recent firmware). The Air streams its IMU over
HID; the One series doesn’t — seeSources/CXrealDriver/device_imu_net.c.- Put the glasses in their plain flat Follow display mode — not the onboard Anchor / Wide
(3840×1080) spatial mode. The X1 anchors the image itself in those modes, which double-tracks
against this app’s own head tracking. (The app warns you if it detects the Wide mode.)- The One Pro’s IMU sits tilted in the frame; the app corrects for it automatically. The Eye
accessory’s 6DoF is computed on-chip and isn’t exposed to the host, so tracking here is 3DoF.

Updates are offered in-app (the right build for your chip is picked automatically). By default you
only see stable releases; Settings → About has an Updates channel picker if you’d like
release candidates or betas early — switching back to Stable offers a clean downgrade.
The app asks for these the first time each is needed (you can manage them under
Settings → Permissions, which links straight to System Settings):
| Permission | Needed for | Required? |
|---|---|---|
| Screen Recording | Capturing your Mac’s screens to show them in the glasses | Yes — AR can’t render without it |
| Accessibility | Moving/arranging windows (⌃⌥W, window layout save & restore) | Optional |
| Microphone | Recording the glasses view with audio | Optional |
| Speech Recognition | Hands-free voice commands (recognition runs on-device) | Optional |
| Calendars | Showing your Apple Calendar agenda on the calendar HUD widget | Optional |
| Reminders | Showing/updating an Apple Reminders list on the List HUD widget | Optional |
| Automation (Apple Events) | Logging you out when you choose Log Out Now after clearing saved display arrangements | Optional |
If you remove a virtual display on a standard (non-admin) account, macOS may ask once for
permission so the app can tidy up that display’s leftover colour profile. This is handled by a
small notarized helper; approve it in System Settings → General → Login Items & Extensions if
prompted. Admin accounts never see this.

Your layout is saved automatically. Create multiple workspaces for different setups and switch
between them from the top bar.

Displays & layout
Head tracking & view
HUD widgets (head-locked, optional)
Voice control (experimental, AR only)

Media player (head-locked video)
Glasses & capture
| Shortcut | Action |
|---|---|
| ⌃⌥S | Start / stop AR |
| ⌃⌥Esc | Stop AR |
| ⌃⌥B | Recalibrate drift (hold the glasses still ~15s) |
| ⌃⌥Space | Recenter the view |
| ⌃⌥F | Focus the screen you’re looking at (toggle) |
| ⌃⌥V | Passthrough — hide / show the screens (HUD stays) |
| ⌃⌥I | Show / hide the HUD widgets |
| ⌃⌥L | Show / hide screen-name labels |
| ⌃⌥W | Move a window to the screen you’re looking at |
| ⌃⌥C | Find the cursor (screen + arrow) |
| ⌃⌥X | Move the cursor to where you’re looking |
| ⌃⌥D | Stereo (SBS) on / off |
| ⌃⌥P | Screenshot the glasses view → Desktop |
| ⌃⌥R | Record the glasses view → Movies |
| ⌃⌥M | Mute / unmute the recording mic |
| ⌃⌥A | Push-to-talk voice command (when voice is enabled) |
| ⌃⌥1–4 | Media: pin the video to a corner (TL · TR · BL · BR) |
| ⌃⌥5 | Media: full view |
| ⌃⌥K | Media: play / pause |
| ⌃⌥← / ⌃⌥→ | Media: rewind / skip 10 s |
| ⌃⌥↑ / ⌃⌥↓ | Media: next / previous in the playlist |
| ⌃⌥0 | Media: stop (keeps the playlist) |
| ⌃⌥H | Show / hide help |
| ⌃⌥Q | Quit AR Workspace Manager |
| ⌃⌥ + brightness keys | Dim / brighten the glasses |
| Esc | Dismiss an active meeting alarm |
Most shortcuts (and their dashboard buttons) only do something while AR is running, so they’re
disabled until you start AR. The exceptions, always available: Help (⌃⌥H), Quit (⌃⌥Q),
Start/Stop AR (⌃⌥S), and Recalibrate (⌃⌥B). Brightness control needs the Air series’ MCU
channel — the One series has no host brightness channel, so adjust it on the glasses themselves.
No picture in the glasses? Make sure they’re plugged into a USB-C port that supports
DisplayPort video, and that macOS sees them as a display (System Settings → Displays). Pick your
output under Settings → Glasses → AR Output if needed.
Head tracking not moving? Check the Dashboard shows Connected. Use ⌃⌥Space to recenter.
On the One series, make sure Ethernet is enabled in the glasses’ menu and they’re in flat
Follow mode (not Anchor/Wide).
Cursor stuck / menu bar missing? The glasses should be an extended display next to your
Mac screen (cursor and menu bar live on the Mac). If they’re your main/only display the pointer
has nowhere to go — set your Mac’s screen as the main display in System Settings → Displays.
On a truly headless Mac (Mac mini, only the glasses), the app promotes a virtual screen to the
main display so the menu bar, Dock and cursor render inside AR.
Microphone prompt never appeared? Recording only requests the mic the first time you record;
if it was previously denied, re-enable it in System Settings → Privacy & Security → Microphone.
High CPU from colorsync.displayservices? This is a macOS-side issue triggered by the glasses
as a display, not the app (XREAL’s own Nebula app provokes it too). The fix: unplug the glasses,
wait ~30 seconds, plug them back in. The Diagnostics page shows the daemon’s live CPU and can
optionally alert you when it’s been stuck for several minutes (“Alert when ColorSync gets
stuck”); see Docs/ColorSync-AirII-investigation.md for
the full investigation (and keep the glasses on their default colour profile).
Virtual displays rely on macOS’s private display APIs, so exact behaviour can vary between macOS
releases.

For developers. Requires the Xcode command-line tools (or Xcode) and Homebrew json-c.
Scripts/build-app.sh # builds + signs "build/AR Workspace Manager.app"
open "build/AR Workspace Manager.app"
With only ad-hoc signing, macOS may re-prompt for permissions after each rebuild; an Apple
Development certificate makes grants stick (Scripts/make-signing-cert.sh sets up a stable
self-signed identity for local use).
Release builds: Scripts/release.sh produces a Developer-ID-signed, notarized, stapled build
(needs a Developer ID Application certificate and a stored notarytool keychain profile — see the
header of Scripts/notarize.sh).
Sources/GlassesDriver — XREAL IMU read loop and pose store (recenter, prediction); picks theSources/CXrealDriver/device_imu_net.c — XREAL One/One Pro IMU over the glasses’ USB-ethernetSources/CapturePipeline — ScreenCaptureKit display capture → Metal texturesSources/Compositor — Metal renderer (flat/curved meshes) driving the glasses displaySources/CPrivateDisplay / Sources/DisplayManager — virtual displays + workspace persistenceSources/VRDesktop — SwiftUI control panel and app lifecycleSources/PrivilegedHelperShared / Sources/VRDesktopHelper / Sources/CXPCAuditToken —Sources/CXrealDriver — vendored C: xrealair-sdk-macos (MIT), xioTechnologies Fusion (MIT),json-c is statically linked from Homebrew (vendor/lib/libjson-c.a)vendor/ clones are gitignored; re-fetch them from
xrealair-sdk-macos,
Fusion, and
hidapi if needed.
Source-available under the PolyForm Noncommercial License 1.0.0: free to use,
modify, and share for any noncommercial purpose — personal use, hobby projects, study,
non-profits, etc. Commercial use and selling are not permitted (don’t repackage or sell it).
This is a source-available license, not an OSI “open source” license, because it restricts
commercial use. For commercial licensing, contact the author.
Bundled third-party components keep their own licenses: MIT code from nrealAirLinuxDriver /
xrealair-sdk-macos and xioTechnologies Fusion, the BSD-licensed hidapi macOS backend
(Sources/CXrealDriver/LICENSE-*), and VLCKit / libVLC (© VideoLAN, LGPL 2.1) for media
playback — dynamically linked and replaceable in the app bundle’s Frameworks folder; license text
ships with the app (About page → “View LGPL license”) and the framework is fetched at build time by
Scripts/fetch-vlckit.sh.
Not affiliated with or endorsed by XREAL.