docs: update TODO_AGENTS — current display_control status + future ideas section
This commit is contained in:
@@ -82,27 +82,35 @@
|
|||||||
|
|
||||||
**Current state (2026-05-20):**
|
**Current state (2026-05-20):**
|
||||||
|
|
||||||
- ✅ Correct `mirror_of_display:<uuid>` syntax used in displayplacer fallback (was `mirror:` — wrong, now fixed)
|
- ✅ Correct `mirror_of_display:<uuid>` syntax used in displayplacer fallback
|
||||||
- ✅ Failures logged to Electron console (`[Launcher] set_display_layout:`) instead of silently swallowed
|
- ✅ Failures logged to Electron console (`[Launcher] set_display_layout:`)
|
||||||
- ✅ **Display Mode toggle** added to Launcher config (Native OS section) — Extend/Mirror buttons always visible, no Technical Mode required
|
- ✅ Display Mode toggle in Launcher config (Native OS section) — always visible
|
||||||
- ⏳ `display_control` binary not yet built — must be compiled on a Mac and committed
|
- ✅ `display_control` binary built (universal x86_64 + arm64), committed to repo
|
||||||
|
- ✅ **Idempotency** — `mirror` and `extend` both no-op with a clean message if already in the requested state (no display flicker)
|
||||||
|
- ✅ **`list-modes`** — JSON array of all online displays + every usable `CGDisplayMode` (width, height, refresh, pixel size, HiDPI flag, is_current)
|
||||||
|
- ✅ **`set-mode`** — sets resolution/refresh via `CGConfigureDisplayWithDisplayMode`; supports `--refresh`, `--hidpi`, `--no-hidpi`; auto-prefers HiDPI on built-in, non-HiDPI on externals
|
||||||
|
- ✅ IPC handlers `native:list-display-modes` + `native:set-display-mode` wired through full bridge stack (system_handlers → preload → types → electron_relay)
|
||||||
|
- ✅ Remote build script (`scripts/remote-build-display-control.sh`) — compiles on laptop-01 via SSH from Linux workstation; uses `ssh cat` pipe pattern (avoids scp space-in-username bug)
|
||||||
|
|
||||||
**To build `display_control` (do this on a Mac):**
|
**To rebuild `display_control` after source changes:**
|
||||||
```bash
|
```bash
|
||||||
# One-time: install Xcode Command Line Tools if not already installed
|
# From repo root on workstation (laptop-01 must be reachable):
|
||||||
xcode-select --install
|
./scripts/remote-build-display-control.sh
|
||||||
|
|
||||||
# Then:
|
# Or directly on a Mac:
|
||||||
./scripts/build-display-control.sh
|
./scripts/build-display-control.sh
|
||||||
|
|
||||||
# Test it with a second display connected:
|
# Test with a second display connected:
|
||||||
./resources/bin/display_control status
|
./resources/bin/display_control status
|
||||||
./resources/bin/display_control extend
|
./resources/bin/display_control extend
|
||||||
./resources/bin/display_control mirror
|
./resources/bin/display_control mirror
|
||||||
|
./resources/bin/display_control list-modes
|
||||||
|
./resources/bin/display_control set-mode 0 1920 1080
|
||||||
|
./resources/bin/display_control set-mode 1 1920 1080 --refresh 60 --no-hidpi
|
||||||
|
|
||||||
# Commit the binary:
|
# Commit:
|
||||||
git add resources/bin/display_control
|
git add resources/bin/display_control
|
||||||
git commit -m "build: add display_control binary (macOS CoreGraphics)"
|
git commit -m "build: update display_control binary (universal)"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Optional per-device override (displayplacer format, for edge cases):**
|
**Optional per-device override (displayplacer format, for edge cases):**
|
||||||
@@ -114,3 +122,27 @@ For rooms where auto-detection produces the wrong result, store the raw configSt
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
`configStr` is passed from the Svelte call site and uses the displayplacer fallback path directly.
|
`configStr` is passed from the Svelte call site and uses the displayplacer fallback path directly.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Ideas
|
||||||
|
|
||||||
|
Capabilities worth adding as the Launcher matures. Roughly ordered by venue-day impact.
|
||||||
|
|
||||||
|
### 1. Display reconfiguration events (push IPC)
|
||||||
|
`CGDisplayRegisterReconfigurationCallback` fires when a display is connected or removed. Wrapping this in a `webContents.send('native:display-changed', payload)` push event would let the Svelte UI auto-mirror the moment a projector cable lands — eliminating the most common operator action during show setup. Currently the UI must poll `status` or the operator presses Mirror manually.
|
||||||
|
|
||||||
|
### 2. Audio output routing
|
||||||
|
When mirroring to a projector the audio output should follow. CoreAudio (`AudioObjectSetPropertyData` on `kAudioHardwarePropertyDefaultOutputDevice`) can switch the default output device programmatically. Candidate bridge method: `set_audio_output({device_name?, prefer_hdmi?})`. Could be called automatically as part of the mirror flow, or exposed as a standalone control.
|
||||||
|
|
||||||
|
### 3. Battery / power status in telemetry
|
||||||
|
`get_device_info` returns CPU and RAM but nothing about power. On venue MacBook Airs this matters operationally. IOKit (`IOPSCopyPowerSourcesInfo` / `IOPSGetPowerSourceDescription`) can surface: charge %, is-charging, time-remaining, health. Low-cost addition to the existing telemetry handler.
|
||||||
|
|
||||||
|
### 4. Presentation state feedback
|
||||||
|
`control_presentation` is fire-and-forget. AppleScript can query the current slide index and total slide count from both PowerPoint (`current slide index of active presentation`) and Keynote (`slide number of current slide of front document`). A `get_presentation_state()` bridge method returning `{ app, slide, total, presenting }` would let the Launcher UI show "Slide 7 of 42" — useful for operators monitoring multiple rooms.
|
||||||
|
|
||||||
|
### 5. Push event channel (IPC renderer notifications)
|
||||||
|
All bridge calls are currently request-response. Adding a `webContents.send` channel for unsolicited Electron → renderer events would unlock: display plug/unplug (#1 above), file download progress, network state changes, "presentation ended" detection. A thin `ipcMain.on('native:subscribe', ...)` registration pattern on the Electron side and a corresponding `ipcRenderer.on` listener in the preload would cover all use cases without breaking the existing handler structure.
|
||||||
|
|
||||||
|
### 6. Kiosk / accidental-quit hardening
|
||||||
|
A speaker or operator can accidentally Cmd+Q the launcher mid-presentation. `app.on('before-quit')` with either a confirmation dialog or an API-controlled lock flag (`event_device.data_json.kiosk_locked: true`) would prevent this. Can be toggled remotely — lock before the show, unlock after.
|
||||||
|
|||||||
Reference in New Issue
Block a user