# Second Display A native macOS app that shows video from a capture device (capture card, camera) in a window and plays audio from a chosen input — a "second monitor". ## Requirements macOS 26+, Xcode (Command Line Tools). ## Build and run ``` make # builds build/Second Display.app make run # build and launch make check # lint: typecheck, plists, translations, signature make install # copy to ~/Applications make dmg # build/second-display-.dmg (universal, not notarized) make help # list targets ``` The app is signed ad-hoc (works on this Mac). For distribution: `make SIGN_ID="Developer ID Application: ..."` (notarization is still required). ## Installation Build from source and install to `~/Applications`: ``` git clone second-display cd second-display make install open "$HOME/Applications/Second Display.app" ``` On first launch macOS asks for camera and microphone access — allow both. You can change this later in System Settings → Privacy & Security. If you received a prebuilt copy (the `.dmg`), drag the app to Applications. It is not notarized, so macOS blocks it on first launch: allow it once in System Settings → Privacy & Security → "Open Anyway", or run `xattr -dr com.apple.quarantine "/Applications/Second Display.app"`. The same steps are in `Read Me First.txt` inside the disk image. ## Releasing a DMG `make dmg` builds a universal (arm64 + x86_64) app and packs it with an `Applications` shortcut and `Read Me First.txt` (source: `Config/dmg/`) in a styled Finder window: large icons and a background with an arrow (`Config/dmg/background.png`, generated by `scripts/make-dmg-background.swift`). The layout is written directly into the image by [dmgbuild](https://github.com/dmgbuild/dmgbuild) (settings in `Config/dmg/settings.py`), so no Finder automation is needed. The first `make dmg` installs it into `build/venv` (needs `python3` and network access). The disk image is not signed with a Developer ID or notarized; the instructions in it explain how recipients allow it. Bump the version in `Config/Info.plist` before releasing and tag it (`git tag -a vX.Y.Z -m vX.Y.Z`). ## Usage Menus at the top of the screen: **Video** (device, format), **Audio** (source or off), **Options** (prevent display sleep, start in full screen, always on top, mute ⇧⌘M, scaling), **Window** (tiling, full screen ⌃⌘F). **Autostart** opens the app whenever the chosen USB capture device is plugged in (and makes it the active video source). It installs a per-user LaunchAgent (`~/Library/LaunchAgents/com.mmacierzanka.seconddisplay.autostart.plist`) matching the device's USB vendor/product ID, so only USB (UVC) devices can be chosen. Choose **Off** to remove it; the uninstall script removes it too. ## Layout - `Sources/` – the app (AppKit + AVFoundation): `App` (state, window), `Capture` (devices, formats), `Menu`, `Power`, `Preferences`, `main` (entry point) - `Config/` – `Info.plist`, entitlements (camera, microphone), `dmg/` (instructions shipped in the disk image) - `Resources/` – icon (`AppIcon.icon`, Icon Composer), en/pl translations, `uninstall.sh` - `scripts/check-strings.sh` – translation consistency ## Settings and uninstall Settings: `~/Library/Preferences/com.mmacierzanka.seconddisplay.plist`. To remove the app and all its traces: `make uninstall` or `"Second Display.app/Contents/Resources/uninstall.sh"`. ## License MIT — see [LICENSE](LICENSE).