diff --git a/README.md b/README.md index 7a8fab8..a0d5597 100644 --- a/README.md +++ b/README.md @@ -296,7 +296,7 @@ to change. | `window_control({action, value?})` | Electron window: maximize, minimize, restore, close, fullscreen, kiosk, devtools, reload. | | `set_wallpaper({path?, url?, url_external?, display?, api_key?, account_id?})` | Sets desktop wallpaper. Accepts a local `path` or downloads from `url` (cached to `~/Library/Caches/OSIT/wallpaper/`). `url_external` sets a separate image on the projector/second display. `display`: `'all'` (default) \| `'primary'` \| `'external'`. macOS only in production; Linux returns a dev-mode preview payload without applying. | | `power_control({action})` | Shutdown, reboot, or sleep. macOS + Linux. Requires sudo for shutdown/reboot. | -| `set_display_layout({mode, configStr?})` | Mirror/extend displays via bundled `displayplacer` binary. macOS only. Auto-detects connected displays via `displayplacer list` when no `configStr` is given — no manual config needed. `configStr` is an optional manual override (the full `displayplacer` config string) stored in `event_device.data_json` if per-device tuning is needed. | +| `set_display_layout({mode, configStr?})` | Mirror/extend displays. macOS only. **Primary path:** bundled `display_control` binary (native CoreGraphics, no Homebrew). **Fallback:** `displayplacer` — used when `display_control` binary is absent, or when a `configStr` override is set. `configStr` is an optional manual override (full `displayplacer` config string) stored in `event_device.data_json` for per-device tuning. Build `display_control` once via `scripts/build-display-control.sh` on a Mac and commit `resources/bin/display_control`. | | `manage_recording({action, options?})` | Screen recording via bundled `aperture` binary. macOS only. | | `update_app(args)` | **Stub.** Downloads update package but does not install. Not functional. | | `list_tools()` | Returns a self-describing manifest of all available bridge functions. | @@ -352,6 +352,33 @@ See `documentation/PROJECT__AE_Events_Launcher_Native_integration.md` Section 8 - **Handlers:** OS-level logic in `src/main/shell_handlers.ts`, `src/main/file_handlers.ts`, and `src/main/system_handlers.ts`. - **Types:** Shared TypeScript interfaces in `src/shared/types.ts`. +### One-Time: Build the `display_control` Binary (macOS) + +The `display_control` binary provides native CoreGraphics display mirror/extend without any Homebrew dependency. It must be compiled once on a Mac and committed to the repo so it is bundled into every packaged app. + +```bash +# Requires Xcode Command Line Tools (one-time install): +xcode-select --install + +# From the repo root: +./scripts/build-display-control.sh + +# Test with a second display connected: +./resources/bin/display_control status +./resources/bin/display_control extend +./resources/bin/display_control mirror + +# Commit the binary: +git add resources/bin/display_control +git commit -m "build: add display_control binary (macOS CoreGraphics)" +``` + +Once committed, `brew install displayplacer` is no longer required on any venue Mac. The `displayplacer` fallback remains in the handler only for `configStr` per-device overrides. + +Rebuild only if `scripts/display_control.m` changes. + +--- + ### Build Requirements (System Dependencies) `bsdtar` (libarchive) must be present on the build host. It is used by the `postinstall` patch diff --git a/src/main/system_handlers.ts b/src/main/system_handlers.ts index ce6ec3b..ba2600a 100644 --- a/src/main/system_handlers.ts +++ b/src/main/system_handlers.ts @@ -335,8 +335,10 @@ export function registerSystemHandlers() { : path.join(__dirname, '../../resources/bin/display_control'); if (fs.existsSync(dc_bin) && !configStr) { - const dc_cmd = mode === 'mirror' ? 'mirror' : 'extend'; - return await runExec(`"${dc_bin}" ${dc_cmd}`); + if (mode !== 'mirror' && mode !== 'extend') { + return { success: false, error: `Unsupported display mode: ${mode}` }; + } + return await runExec(`"${dc_bin}" ${mode}`); } // Fallback: displayplacer — required when display_control binary is not built yet,