Skip to content

feat(macOS): add persistent landscape camera preview - #1333

Closed
ouerf-man wants to merge 2 commits into
getopenscreen:mainfrom
ouerf-man:integration/floating-camera-preview
Closed

ouerf-man wants to merge 2 commits into
getopenscreen:mainfrom
ouerf-man:integration/floating-camera-preview

Conversation

@ouerf-man

@ouerf-man ouerf-man commented Oct 18, 2026 •

Copy link
Copy Markdown

Summary

When Camera is enabled on macOS, there is no persistent live view to check framing while recording. This adds a borderless landscape preview that opens automatically and survives the transition from the recording bar to Studio.

  • Rounded corners, with move/hide controls and four resize handles on hover or keyboard focus. Arrow keys move/resize; Shift takes larger steps. View → Show camera preview reopens it without interrupting a take.
  • An independent preview stream follows the selected camera by ID/name and stops when hidden. The recorder's separate camera track stays independent. CLI, headless and benchmark runs do not open the preview.
  • Prefer negotiable 16:9 webcam capture with crop-and-scale, preserving the selected quality and lower-resolution camera support.
  • Precreate a stable native window before source selection, exclude it from both macOS capture paths, and enumerate hidden windows in ScreenCaptureKit so showing it mid-take does not bake it into the screen video. Dispose of lingering preview/countdown windows when the main window closes.
  • Translate the new controls across all 15 locales.

Related issue

Refs #1278 and #1274.

Related alternative: #1288. This implementation uses a persistent landscape window, including Studio, an independent preview stream, and hover/corner resizing. It is intended as an alternative for maintainer review; it does not depend on that PR.

Type of change

  • Bug fix
  • Feature
  • Enhancement
  • Documentation
  • Refactor / maintenance
  • Performance
  • Security

Release impact

  • Patch
  • Minor
  • Major / breaking change
  • No release note needed

Desktop impact

  • Windows
  • macOS
  • Linux
  • Installer / packaging
  • Not platform-specific

The floating window is macOS-only. The browser webcam constraint preference is shared; native Windows webcam capture is unchanged.

Screenshots / video

Synthetic SMPTE camera input, captured from the real Electron app. No physical camera feed or desktop capture is included in these images.

Idle Hover / keyboard controls
Borderless landscape preview Move, hide and resize controls

Reproduction commands and the images are in technical-documentation/testing/assets/camera-preview/.

Testing

  • Both app and test TypeScript configurations pass.
  • npm run lint:fix, npm run i18n:check, npm run docs:check, npm run build-vite pass. Lint reports existing warnings, no errors.
  • Final-branch GitHub CI is green, including Windows/macOS/Linux compositor checks and Swift tests. Unit suite: 4,930 passed, 7 platform skips, zero failures.
  • Local full unit run: 4,928 passed / 4 timed out / 1 skipped under local resource contention. Reran both affected existing UI files with one worker: 171/171 passed. Focused preview, geometry, lifecycle and constraints tests pass, including a later CLI/headless guard test.
  • Real CLI smoke: electron . --user-data-dir=<isolated-profile> sources --json -o <result> succeeds with Camera enabled in that profile, without creating a camera preview window.
  • Rebuilt the macOS helper from source; npm run test:swift:mac: 65/65 passed.
  • Real desktop smoke on macOS 26.2 / Apple Silicon / FaceTime HD Camera: live stream and saved camera file are 1920×1080; hide/reopen and keyboard resize work; native full-display recording began with the preview hidden, then showed it mid-take. A raw screen frame at 65 seconds of the 90.58-second take contains the desktop behind the preview without the preview itself. Camera is saved separately. Stop opens Studio and its independent live preview remains available.
  • The first cold helper launch timed out while the local machine was overloaded; retry with the rebuilt helper succeeded. The manual checklist records this and all skipped checks.

Not covered by the desktop pass: Apple system picker (OPENSCREEN_MAC_SOURCE_PICKER=legacy used), older macOS, Windows/Linux desktop runs, export, and native pointer dragging (computer-use rejected this window's position on the two-display setup; geometry and keyboard controls are covered). See the Partial entry in technical-documentation/testing/manual-e2e-checklist.md.

Summary by CodeRabbit

  • New Features
    • Added a floating live camera preview on macOS, with controls to hide, move, and resize it. Reopen it from the View menu.
    • The preview follows camera availability and recording preferences, and can be used while recording or in Studio.
  • Improvements
    • Camera capture now prefers a 16:9 aspect ratio with cropping and scaling for a more consistent preview.
  • Documentation
    • Added guidance for reproducing preview screenshots and manual testing.

@coderabbitai

coderabbitai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 19cb14f0-6d0b-4057-b359-93879813c29c
📥 Commits

Reviewing files that changed from the base of the PR and between 91a8b8c and 1719206.

⛔ Files ignored due to path filters: 2
  • technical-documentation/testing/assets/camera-preview/controls.png is excluded by !**/*.png
  • technical-documentation/testing/assets/camera-preview/idle.png is excluded by !**/*.png
📒 Files selected for processing: 51
  • electron/cameraPreview.test.ts
  • electron/cameraPreview.ts
  • electron/cameraPreviewBounds.test.ts
  • electron/cameraPreviewBounds.ts
  • electron/electron-env.d.ts
  • electron/ipc/handlers.ts
  • electron/lingeringOverlay.test.ts
  • electron/lingeringOverlay.ts
  • electron/main.ts
  • electron/native/screencapturekit/Sources/OpenScreenScreenCaptureKitHelper/ScreenCaptureRecorder.swift
  • electron/preload.ts
  • electron/windows.ts
  • src/App.tsx
  • src/components/launch/CameraPreviewWindow.module.css
  • src/components/launch/CameraPreviewWindow.test.tsx
  • src/components/launch/CameraPreviewWindow.tsx
  • src/hooks/webcamCaptureTarget.test.ts
  • src/hooks/webcamCaptureTarget.ts
  • src/i18n/locales/ar/common.json
  • src/i18n/locales/ar/launch.json
  • src/i18n/locales/cs/common.json
  • src/i18n/locales/cs/launch.json
  • src/i18n/locales/de/common.json
  • src/i18n/locales/de/launch.json
  • src/i18n/locales/en/common.json
  • src/i18n/locales/en/launch.json
  • src/i18n/locales/es/common.json
  • src/i18n/locales/es/launch.json
  • src/i18n/locales/fr/common.json
  • src/i18n/locales/fr/launch.json
  • src/i18n/locales/it/common.json
  • src/i18n/locales/it/launch.json
  • src/i18n/locales/ja-JP/common.json
  • src/i18n/locales/ja-JP/launch.json
  • src/i18n/locales/ko-KR/common.json
  • src/i18n/locales/ko-KR/launch.json
  • src/i18n/locales/pt-BR/common.json
  • src/i18n/locales/pt-BR/launch.json
  • src/i18n/locales/ru/common.json
  • src/i18n/locales/ru/launch.json
  • src/i18n/locales/tr/common.json
  • src/i18n/locales/tr/launch.json
  • src/i18n/locales/vi/common.json
  • src/i18n/locales/vi/launch.json
  • src/i18n/locales/zh-CN/common.json
  • src/i18n/locales/zh-CN/launch.json
  • src/i18n/locales/zh-TW/common.json
  • src/i18n/locales/zh-TW/launch.json
  • src/lib/cameraPreview.ts
  • technical-documentation/testing/assets/camera-preview/README.md
  • technical-documentation/testing/manual-e2e-checklist.md

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

📝 Walkthrough

Adds a macOS floating camera preview with synchronized camera state, move and resize controls, and hide and show actions. Integrates the preview with application lifecycle and recording capture, adds localized controls, and includes automated and manual test coverage.

Changes: Camera preview

Layer / File(s) Summary
Electron preview state and geometry
src/lib/cameraPreview.ts, electron/cameraPreview.ts, electron/cameraPreviewBounds.ts, electron/windows.ts, electron/preload.ts, electron/electron-env.d.ts, electron/cameraPreview*.test.ts
Defines preview state and commands, creates and manages the macOS preview window, and exposes state, hide, and transform APIs. Move and resize commands are validated and constrained to display work areas.
Renderer preview and controls
src/components/launch/CameraPreviewWindow.*, src/hooks/webcamCaptureTarget.*, src/i18n/locales/*/{common,launch}.json, technical-documentation/testing/assets/camera-preview/README.md
Adds the preview interface, camera stream handling, pointer and keyboard controls, and localized labels. Camera constraints include an ideal aspect ratio and crop-and-scale resizing.
Application lifecycle and capture integration
src/App.tsx, electron/main.ts, electron/lingeringOverlay.*, electron/ipc/handlers.ts, electron/native/screencapturekit/.../ScreenCaptureRecorder.swift, technical-documentation/testing/manual-e2e-checklist.md
Integrates the preview with application startup, activation, menu actions, and overlay cleanup. Synchronizes it with recording preferences, excludes it from capture selection, and records macOS manual test results.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant CameraPreviewWindow
  participant electronAPI
  participant cameraPreview as cameraPreview.ts
  participant BrowserWindow
  CameraPreviewWindow->>electronAPI: Request preview state or send transform command
  electronAPI->>cameraPreview: Forward preview IPC request
  cameraPreview->>BrowserWindow: Publish state or update preview bounds
  cameraPreview-->>electronAPI: Return preview state
  electronAPI-->>CameraPreviewWindow: Deliver state or completion
Loading
Merge Risk: ⚪ Minimal · up to 17192

The macOS camera preview feature works as described, and Studio entry restores the preview by design. No merge-blocking risk remains after the final review.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 45.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 20 functions across 18 files. (33 skipped… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description check Passed The description is complete and follows the repository template. It explains the feature, related issues, change type, release impact, macOS scope, visual changes, and detailed testing results, includ…
Title check Passed The title is concise, specific, and accurately identifies the primary change: a persistent landscape camera preview for macOS.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description is complete and follows the repository template. It explains the feature, related issues, change type, release impact, macOS scope, visual changes, and detailed testing results, including known limitations.

Full details: Docstring Coverage

Explanation

Docstring coverage is 45.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 20 functions across 18 files. (33 skipped: 33 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

🔧 LanguageTool
technical-documentation/testing/manual-e2e-checklist.md

LanguageTool checks are incomplete because the per-file request limit of 5 was reached. Remaining text was skipped; findings from completed checks are retained.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@EtienneLescot

Copy link
Copy Markdown
Member

Thanks @ouerf-man, this is careful work and the test write-up is excellent. We can only take one camera preview, and we're going with #1288: it came first from the author of #1278, it reuses the recorder's camera stream instead of opening the camera twice, and it doesn't carry the preview into Studio, which we don't need. I'll ask there for the true landscape frame you made the case for.

The part we'd really like to keep is the 16:9 fix for #1274. Could you open it as its own small PR, just the webcamCaptureTarget change and its tests? It touches the webcam path on every platform, so I'd like to check it against the native mode selection from #875 in isolation. I'll close this one meanwhile. Thanks again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants