[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-92288":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":20,"hasPages":22,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":36,"readmeContent":37,"aiSummary":38,"trendingCount":16,"starSnapshotCount":16,"syncStatus":39,"lastSyncTime":40,"discoverSource":41},92288,"opendisplay","peetzweg\u002Fopendisplay","peetzweg","Free, open-source Sidecar\u002FDuet alternative — use your iPhone or iPad as a true second monitor for your Mac over USB or WiFi. Low latency H.264, Retina HiDPI, touch input.","https:\u002F\u002Fopendisplay.app",null,"Swift",885,72,161,41,0,655,59.59,"GNU General Public License v3.0",false,"main",true,[24,25,26,27,28,29,30,31,32,33,34,35],"duet-display","external-display","ipad","iphone","macos","screen-extension","screencapturekit","second-monitor","sidecar","swift","videotoolbox","virtual-display","2026-07-22 04:02:05","\u003Cdiv align=\"center\">\n\n\u003Cimg src=\"public\u002Flogo.png\" width=\"128\" alt=\"OpenDisplay app icon\" \u002F>\n\n# OpenDisplay\n\n**Turn your spare Apple devices into second monitors for your Mac — free, open source, no subscription.**\n\niPhone and iPad today, spare MacBooks on the roadmap. A self-hosted\nalternative to Apple Sidecar, Duet Display, and Luna Display: true extended\ndisplay (not just mirroring), Retina-sharp, over USB or WiFi, with touch and\nscroll input.\n\n[Website](https:\u002F\u002Fpeetzweg.github.io\u002Fopendisplay\u002F) · [Quick start](#quick-start) · [How it works](#how-it-works) · [FAQ](#faq) · [Contributing](#contributing)\n\n\u003C\u002Fdiv>\n\n---\n\n## Why OpenDisplay exists\n\nTurning an iPhone or iPad into an external display for a Mac is a solved\nproblem — but every existing option has a catch:\n\n- **Apple Sidecar** is free but requires both devices on the *same Apple ID*,\n  doesn't support iPhones at all, and only works on supported hardware pairs.\n- **Duet Display** moved to a subscription.\n- **Luna Display** requires a hardware dongle.\n\nOpenDisplay is the missing option: a **free, open-source, no-account,\nno-dongle** way to use the iOS device you already own as a true second\ndisplay. If you were about to write your own — don't! Contribute here\ninstead; the hard parts (virtual display creation, low-latency H.264\npipeline, USB transport, input injection) are already working.\n\n## Features\n\n- 🖥️ **True display extension** — macOS treats the device as a real second\n  monitor (drag windows to it, arrange it in System Settings), not a mirror.\n  Mirroring is also available as a mode.\n- 🔌 **USB-wired for lowest latency** — streams over the Lightning\u002FUSB-C\n  cable via macOS's built-in `usbmuxd`; plug in and go, no network, no\n  WiFi jitter, no helper tools.\n- 📶 **WiFi with zero config** — the iPhone advertises itself via Bonjour;\n  pick it from a dropdown on the Mac.\n- 🔍 **Retina \u002F HiDPI** — the virtual display matches the device panel\n  pixel-for-pixel (@2x), so text is sharp.\n- 👆 **Touch input built in** — your iPhone becomes a touchscreen for macOS:\n  **tap to click**, **drag to drag**, and **two-finger scroll** that feels\n  like a trackpad. (Apple Pencil support is on the roadmap.)\n- 🔄 **Portrait or landscape** — rotate the device and the virtual display\n  rebuilds itself as a vertical monitor at native resolution.\n- ⚡ **Low-latency pipeline** — hardware H.264 encode (VideoToolbox,\n  real-time mode, no B-frames), TCP_NODELAY, frame-drop backpressure with\n  keyframe recovery, decode-and-render via `AVSampleBufferDisplayLayer`.\n- 🔒 **Self-hosted & private** — your screen never touches anyone's server.\n  Two small apps, one TCP connection, that's it.\n\n## How it works\n\n```\nMAC (sender)                                      iPHONE \u002F iPAD (receiver)\nCGVirtualDisplay  ← macOS believes a monitor is attached\n   → ScreenCaptureKit (capture the virtual display)\n   → VideoToolbox H.264 (hardware, real-time)\n   → TCP  [4-byte length][Annex B frame]  ═══════→  NWListener :9000\n                                                      → AVSampleBufferDisplayLayer\n   ← JSON control messages (hello, touch, scroll) ═══\n   → CGEvent injection (click \u002F drag \u002F scroll)\n```\n\nThe **phone listens and the Mac connects** — that ordering is what makes the\nexact same code work over USB (via the `usbmuxd` daemon built into every\nmacOS install) and WiFi. The phone\nannounces its native panel size; the Mac creates a `CGVirtualDisplay` at\nexactly half that in points (@2x HiDPI) and streams the pixels back.\n\n`CGVirtualDisplay` is a **private CoreGraphics API** (the same one used by\nBetterDisplay and DeskPad) — which is precisely why this project can't ship\non the App Store and lives on GitHub instead.\n\n## Install\n\nYou need **two apps**: a Mac app (captures and sends) and an iOS app\n(receives and displays).\n\n### Prebuilt downloads (Mac)\n\nGrab `OpenDisplay.dmg` from the\n[latest release](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Freleases\u002Flatest).\nThe app is signed with a Developer ID certificate and notarized by Apple, so it\nopens with a plain double-click on macOS 14+ — no Gatekeeper warning. Open the\n`.dmg` and drag the app to Applications.\n\n### iPhone app\n\n- **TestFlight** (recommended): join the public beta at\n  [testflight.apple.com\u002Fjoin\u002F3NYaY11c](https:\u002F\u002Ftestflight.apple.com\u002Fjoin\u002F3NYaY11c).\n- **Build from source**: open the project in Xcode, select your free Apple ID\n  under Signing, hit Run. Takes ~2 minutes.\n\n## Quick start (from source)\n\n### Prerequisites\n\n```sh\nbrew install xcodegen   # project generation\n```\n\nXcode 15+ and a free or paid Apple developer account (to sideload the iOS\napp onto your device).\n\n### Build\n\n```sh\ngit clone https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay.git\ncd opendisplay\necho \"DEVELOPMENT_TEAM=YOURTEAMID\" > .env   # your Apple team ID, for signing\n.\u002Fgenerate.sh                               # runs xcodegen with your .env\nxcodebuild -project OpenSidecar.xcodeproj -scheme OpenSidecarMac \\\n  -configuration Debug -derivedDataPath build build\nxcodebuild -project OpenSidecar.xcodeproj -scheme OpenSidecariOS \\\n  -configuration Debug -destination 'generic\u002Fplatform=iOS' \\\n  -derivedDataPath build -allowProvisioningUpdates build\n```\n\n(Or open `OpenSidecar.xcodeproj` in Xcode and hit Run on each target. Your\nteam ID is shown at [developer.apple.com\u002Faccount](https:\u002F\u002Fdeveloper.apple.com\u002Faccount)\nunder Membership, or just pick your team in Xcode's Signing pane.)\n\n### Run (USB — recommended)\n\n1. Install + open **OpenDisplay** on the iPhone (it listens on port 9000).\n2. On the Mac, run `.\u002Frun.sh` (or just open the app) — it talks to macOS's\n   built-in `usbmuxd` directly and auto-connects over the cable. No tunnel\n   tools needed.\n3. Grant **Screen Recording** (for capture) and **Accessibility** (for touch)\n   when macOS asks — one time each.\n4. Drag a window onto your new display. Done.\n\n### Run (WiFi)\n\nOpen the iPhone app, then pick **\"iPhone (WiFi)\"** from the Connection menu\nin the Mac app. Discovery is automatic via Bonjour. USB has lower latency;\nWiFi has no cable.\n\n### Permissions checklist\n\nmacOS and iOS gate several things this app needs — most prompt on first use,\nbut some **fail silently** if denied or missed. The Mac app shows a live\npermission status panel; the iPhone app has a settings screen (shake the\nphone, or tap Settings & Help when idle).\n\n| Where | Permission | Needed for | If missing |\n|---|---|---|---|\n| Mac | Screen Recording | capturing the display | black screen on the phone |\n| Mac | Accessibility | touch\u002Fscroll input | taps do nothing |\n| Mac | **Local Network** | WiFi discovery | no device in the Connection menu |\n| iPhone | **Local Network** | WiFi discovery | Mac can't find the phone |\n\nAll live under **Privacy & Security** in System Settings (Mac) \u002F Settings\n(iPhone). The Local Network ones are only needed for WiFi mode — USB works\nwithout them. If the prompt never appeared, toggle the entry manually or\nforce-quit and reopen the app.\n\n## FAQ\n\n**Why do I see the purple screen-recording indicator in the menu bar?**\nThat's a macOS privacy indicator shown for *any* app that captures the\nscreen — Duet, Luna, OBS, and Zoom trigger it too. Apple Sidecar doesn't,\nonly because it's implemented inside the OS rather than on public capture\nAPIs. It cannot (and shouldn't) be hidden by an app; it's how macOS tells\nyou a capture is running.\n\n**The Mac app doesn't show my iPhone in the Connection menu (WiFi).**\nBoth sides need **Local Network** permission, and both fail *silently*\nwithout it: check Privacy & Security → Local Network on the Mac **and** on\nthe iPhone, make sure both are on the same WiFi network, and keep the\niPhone app open in the foreground. USB mode is unaffected.\n\n**Does it support iPad?** The receiver app is universal (iPhone + iPad);\niPad is the same codebase. iPad-specific polish (Pencil, pressure) is on the\nroadmap.\n\n**Why H.264 and not HEVC\u002FAV1?** Hardware H.264 encode\u002Fdecode is universally\nfast and the latency is excellent. HEVC is a planned option for better\nquality-per-bit.\n\n**Is my screen content sent anywhere?** No. One direct TCP connection\nbetween your Mac and your device, over your cable or your LAN. No servers,\nno accounts, no analytics. Full details — including what the apps store\nlocally and the current WiFi-encryption caveat — on the\n[privacy page](https:\u002F\u002Fpeetzweg.github.io\u002Fopendisplay\u002Fprivacy.html).\n\n**What's the license? Can I fork it or use it commercially?**\n[GPL-3.0](LICENSE). Use, study, and adapt it freely — commercially too. If\nyou distribute a modified version it must stay open source under the same\nlicense with the original attribution intact, so improvements flow back\ninstead of into closed forks. (Releases up to v0.4.x were MIT-licensed and\nremain available under those terms.)\n\n**Will it break on a macOS update?** Possibly — `CGVirtualDisplay` is\nprivate API. The same risk applies to every virtual-display product.\nThe capture\u002Fstreaming pipeline itself uses only public APIs.\n\n**Audio?** Out of scope for now.\n\n## Comparison\n\n| | OpenDisplay | Apple Sidecar | Duet Display | Luna Display |\n|---|---|---|---|---|\n| Price | **Free, open source** | Free | Subscription | $$$ + dongle |\n| iPhone as display | ✅ | ❌ (iPad only) | ✅ | ✅ |\n| Different Apple IDs | ✅ | ❌ | ✅ | ✅ |\n| Wired (USB) | ✅ | ✅ | ✅ | ❌ |\n| True extension | ✅ | ✅ | ✅ | ✅ |\n| Touch input | ✅ | ✅ | ✅ | ✅ |\n| Self-hosted \u002F auditable | ✅ | — | ❌ | ❌ |\n\n## Roadmap\n\nTracked as [roadmap issues](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues?q=is%3Aissue+is%3Aopen+label%3Aroadmap) — pick one up if you'd like to contribute!\n\n**Connectivity & distribution**\n- [#16](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F16) Encrypted WiFi transport with pairing code\n- [ ] App Store release of the iOS app + notarized Mac downloads\n\n**Input**\n- [#4](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F4) Apple Pencil with pressure and tilt\n- [#5](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F5) Right-click and multi-touch gestures\n- [#6](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F6) Hardware keyboard passthrough\n- [#7](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F7) On-screen modifier key sidebar\n\n**Display & media**\n- [#9](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F9) Resolution & quality settings\n- [#10](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F10) HEVC encoding\n- [#12](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F12) Audio forwarding\n- [#17](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F17) macOS receiver — use another Mac as a display\n\n**Experience**\n- [#11](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F11) Menu bar app mode with auto-connect\n- [#13](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F13) Battery & lifecycle awareness\n\n**Exploratory**\n- [#14](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F14) Remote access beyond the local network\n- [#15](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F15) Additional client platforms\n\nDone: prebuilt releases, built-in USB connectivity (no helper tools), WiFi via Bonjour, portrait mode, touch + two-finger scroll, performance overlay, iPad support, multiple devices at once ([#8](https:\u002F\u002Fgithub.com\u002Fpeetzweg\u002Fopendisplay\u002Fissues\u002F8) — every connected device becomes its own extended display).\n\n## Auto-update (macOS app)\n\nThe macOS app updates itself with [Sparkle](https:\u002F\u002Fsparkle-project.org) —\nan open-source framework, **not** a hosted service. Update checks hit only\nour own infrastructure:\n\n- The app reads an **appcast** feed hosted on the landing-page site:\n  `https:\u002F\u002Fopendisplay.app\u002Fappcast.xml` (`SUFeedURL` in `project.yml`).\n- The release workflow (`.github\u002Fworkflows\u002Frelease.yml`, `build-mac` job)\n  runs Sparkle's `generate_appcast` against the notarized `OpenDisplay.dmg`,\n  signs it with the EdDSA key, commits the result to `public\u002Fappcast.xml`,\n  and dispatches the Pages deploy — so the published feed points download\n  links at the GitHub Release assets.\n- Sparkle verifies both the EdDSA signature and Apple's notarization before\n  installing. The app checks automatically in the background\n  (`SUEnableAutomaticChecks`) and offers a manual **\"Check for Updates…\"**\n  button next to **Quit** in the menu-bar window.\n\n### Maintainer prerequisites (before auto-update goes live)\n\nAuto-update is **scaffolded but inert** until the signing keys are in place.\nThe private signing key is **never** committed — it lives only as a CI\nsecret. To switch it on:\n\n1. **Generate the key pair.** Run Sparkle's `generate_keys` once (it ships\n   in the Sparkle SPM artifact bundle and in the release tarball at\n   `bin\u002Fgenerate_keys`). It prints a **public** key and stores the\n   **private** key in your login keychain.\n2. **Public key →** paste it into `SUPublicEDKey` in `project.yml` (replace\n   the `REPLACE_WITH_SUPUBLICEDKEY_FROM_generate_keys` placeholder), then\n   re-run `xcodegen generate` and commit.\n3. **Private key →** add it as the `SPARKLE_PRIVATE_KEY` GitHub Actions\n   secret (export it with `generate_keys -x private_key.pem` if needed). The\n   appcast step in `release.yml` no-ops gracefully while this secret is\n   absent, so releases keep working until you're ready.\n4. The **first appcast publishes on the next release** after both keys are\n   set. Confirm `https:\u002F\u002Fopendisplay.app\u002Fappcast.xml` resolves, then **test\n   the full update flow on a real signed\u002Fnotarized build** (check → download\n   → verify → relaunch) — this can't be validated in CI.\n\n## Contributing\n\nIssues and PRs are very welcome — especially for the roadmap items above.\nThe codebase is intentionally small: ~4 Swift files per platform, with\n[Sparkle](https:\u002F\u002Fsparkle-project.org) (SPM) as the macOS app's only\nruntime dependency, for auto-update. The [How it works](#how-it-works)\nsection above is the architecture doc; see `Mac\u002FCGVirtualDisplayPrivate.h`\nfor the private API surface.\n\nReleases are automated with\n[release-please](https:\u002F\u002Fgithub.com\u002Fgoogleapis\u002Frelease-please): use\n[Conventional Commits](https:\u002F\u002Fwww.conventionalcommits.org) (`feat:`,\n`fix:`, `docs:`, …) and a release PR with a generated changelog appears\nautomatically — merging it tags the release and attaches prebuilt\nartifacts.\n\n## License\n\n[GPL-3.0](LICENSE) — Copyright (c) 2026 Philip Poloczek.\n\nFree to use, study, and adapt. If you distribute a modified version it\nmust remain open source under the same license, with the original\nattribution intact — improvements flow back to everyone instead of into\nclosed forks. (Versions up to v0.4.x were MIT-licensed; those releases\nremain available under MIT.)\n\n---\n\n*Keywords: iPhone second monitor Mac, iPad external display, free Sidecar\nalternative, Duet Display alternative, open source screen extension macOS,\nuse iPhone as extra screen, virtual display Mac, USB second display.*\n","OpenDisplay 是一个免费开源的 macOS 工具，将 iPhone 或 iPad 变身为真正的第二显示器（非镜像），支持 USB 有线低延迟和 Wi-Fi 零配置连接。核心功能包括：基于 ScreenCaptureKit 和 VideoToolbox 的硬件加速 H.264 编码、Retina 级 HiDPI 显示适配、完整触控输入（点击\u002F拖拽\u002F双指滚动）、横竖屏自动适配及虚拟显示器系统集成。适用于需要低成本、隐私优先、无订阅与无硬件依赖的多屏办公、设计辅助或移动扩展场景。",2,"2026-07-08 04:30:00","CREATED_QUERY"]