Skip to content

Fix selected recording target highlight#719

Open
chbndrhnns wants to merge 3 commits into
webadderallorg:mainfrom
chbndrhnns:fix/source-highlight-718
Open

Fix selected recording target highlight#719
chbndrhnns wants to merge 3 commits into
webadderallorg:mainfrom
chbndrhnns:fix/source-highlight-718

Conversation

@chbndrhnns

@chbndrhnns chbndrhnns commented Jun 30, 2026

Copy link
Copy Markdown

Fixes #718

Summary:

  • Add a capture-protected green source highlight window for selected and hovered recording targets.
  • Keep the highlight visible during recording without recording it, and clear it on idle HUD hide/cleanup paths.
  • Use macOS visible-window bounds so hidden windows are not highlighted while partially visible windows still are.

Verification:

  • npx tsc --noEmit
  • npm test

Summary by CodeRabbit

  • New Features
    • Added hover-based source preview/highlight in the launcher and source popovers.
    • Source highlight can now be controlled to avoid stealing focus (activation is configurable).
  • Bug Fixes
    • Improved reliability of clearing source highlights when switching sources, closing the HUD, quitting, or starting recording.
    • Linux now clears highlights instead of attempting unsupported overlay rendering.
    • Enhanced macOS highlight positioning using visible-area calculations for better on-screen containment.
  • Tests
    • Added/updated tests covering source-highlight window behavior, hover preview request gating, and macOS geometry stability.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: fd508130-09fe-4d63-8a0d-5c60dd07e1e8

📥 Commits

Reviewing files that changed from the base of the PR and between 80f7463 and 5bef9ec.

📒 Files selected for processing (1)
  • electron/native/ScreenCaptureKitWindowListGeometry.test.ts

📝 Walkthrough

Walkthrough

Adds source highlight overlay support across native visible-bounds data, a shared Electron overlay controller, IPC bridging for show/clear actions, and launch UI hover/selection flows that drive the highlight lifecycle.

Changes

Source Highlight Overlay Feature

Layer / File(s) Summary
Native visible-bounds data
electron/native/ScreenCaptureKitWindowList.swift, electron/ipc/types.ts, electron/ipc/cursor/bounds.ts, electron/native/ScreenCaptureKitWindowListGeometry.test.ts
Adds native window visibility fields, computes visible bounds from CoreGraphics window stacks, resolves Mac visible bounds from refreshed native sources, and adds a Swift geometry integration test.
Highlight controller and window API
electron/sourceHighlightController.ts, electron/sourceHighlight.ts, electron/sourceHighlightController.test.ts
Defines the highlight overlay controller, HTML payload, bounds adjustment, reuse/clear lifecycle, and the wrapper API that creates and clears the window.
IPC bridge and lifecycle clearing
electron/electron-env.d.ts, electron/preload.ts, electron/ipc/register/sources.ts, electron/ipc/register/recording.ts, electron/main.ts
Updates the renderer API contract and preload bridge, rewrites the IPC handler to delegate to the shared controller, and clears highlight state during recording start, quit, and HUD close events.
Windows helper path resolution
electron/ipc/paths/binaries.ts
Adds Windows-specific native helper path resolution and switches preferred helper lookup to the new path helper.
Launch window highlight interactions
src/components/launch/LaunchWindow.tsx, src/components/launch/SourceSelector.tsx, src/components/launch/popovers/SourcePopover.tsx, src/components/launch/popovers/sourcePreviewRequestGate.ts, src/components/launch/popovers/sourcePreviewRequestGate.test.ts, src/components/launch/hooks/useLaunchWindowActions.ts, src/hooks/useScreenRecorder.ts
Adds hover-preview callbacks, request gating, selected-source highlight syncing, Linux clear paths, and recording-start highlight calls across the launch UI and recording hooks.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~100 minutes

Possibly related PRs

Poem

🐇 A border blooms where targets glow,
I hop along and help it show.
Hover, click, or start to record—
The right window now is neatly scored.
Clear the haze, then shine once more,
A bunny frame on every floor ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and directly describes the main highlight-related change.
Linked Issues check ✅ Passed The PR implements the requested hover/selection target border highlight described in #718.
Out of Scope Changes check ✅ Passed The added code and tests all support the target-highlight feature and no unrelated changes stand out.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
electron/native/ScreenCaptureKitWindowList.swift (1)

92-156: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Add focused coverage for the rectangle visibility math.

subtract and unionRect now drive user-visible highlight bounds; fixture tests for touching edges, full occlusion, nested occluders, and disjoint visible regions would make this safer to evolve.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@electron/native/ScreenCaptureKitWindowList.swift` around lines 92 - 156, Add
focused tests for the rectangle visibility math in subtract and unionRect so the
highlight bounds behavior is covered. Create fixture cases for touching edges,
full occlusion, nested occluders, and disjoint visible regions, and assert the
returned WindowRect pieces and merged bounds match expectations. Keep the tests
targeted around the existing subtract(_:from:) and unionRect(_:) helpers so
future changes to ScreenCaptureKitWindowList remain safe.
electron/sourceHighlightController.test.ts (1)

105-116: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the HUD passthrough reassertion in the clear-path test.

clear() is also responsible for calling reassertHudOverlayMousePassthrough(), and that lifecycle side effect is part of what this PR is adding. The current test only checks close(), so that regression would still pass.

Suggested test tweak
 it("clears the persistent recording outline explicitly", async () => {
 	const highlightWindow = createMockHighlightWindow();
+	const reassertHudOverlayMousePassthrough = vi.fn();
 	const controller = createSourceHighlightController({
 		createWindow: vi.fn(() => highlightWindow),
-		reassertHudOverlayMousePassthrough: vi.fn(),
+		reassertHudOverlayMousePassthrough,
 	});

 	await controller.show({ x: 0, y: 0, width: 200, height: 100 });
 	controller.clear();

 	expect(highlightWindow.close).toHaveBeenCalledTimes(1);
+	expect(reassertHudOverlayMousePassthrough).toHaveBeenCalled();
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@electron/sourceHighlightController.test.ts` around lines 105 - 116, Update
the source highlight controller clear-path test to also verify the HUD
passthrough reassertion side effect. In the `createSourceHighlightController`
setup, keep a spy for `reassertHudOverlayMousePassthrough`, then in the
`clear()` flow assert that this callback is invoked in addition to
`highlightWindow.close()` so the `clear` lifecycle in
`sourceHighlightController` is fully covered.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@electron/ipc/register/sources.ts`:
- Around line 53-65: getVisibleWindowHighlightBounds currently returns only the
largest display intersection, which collapses multi-display windows to a single
monitor. Update this helper to preserve all positive intersections from
getScreen().getAllDisplays() by combining them into one cross-display highlight
shape instead of sorting and selecting intersections[0]. Keep the logic
localized in getVisibleWindowHighlightBounds and ensure the controller can
receive the full visible region across displays.

In `@src/components/launch/LaunchWindow.tsx`:
- Around line 191-199: The initial getSelectedSource() handling in LaunchWindow
should clear any existing overlay when the returned source is falsy, not only on
Linux. Update the then() branch around syncSelectedSource and
showSelectedSourceHighlight so that it mirrors the subscription logic and calls
window.electronAPI.clearSourceHighlight?.() whenever source is null/undefined,
regardless of platform, while still showing the highlight only when source
exists and canShowSourceHighlight is true.

In `@src/components/launch/popovers/SourcePopover.tsx`:
- Around line 79-81: The hover flow in SourcePopover’s showSourceHighlight calls
is treating any resolved preload response as success, but the contract can
return { success: false } and that case must be handled. Update the
highlight/restore paths around showSourceHighlight and restoreSourceHighlight to
check the returned success flag and avoid clearing or leaving stale UI state
when highlighting fails, so the previous border/overlay is not left visible. Use
the existing SourcePopover hover handlers and the
window.electronAPI?.showSourceHighlight?. calls as the anchor points for the
fix.

In `@src/hooks/useScreenRecorder.ts`:
- Line 1522: The recording source highlight is being re-shown too early in the
start-recording flow, so it gets cleared again by the recording-start IPC
transition. Update the relevant start paths in useScreenRecorder (the
selectedSource/platform highlight handling in both flows noted in the review) to
re-show the overlay only after the recording-start IPC has settled, or adjust
electron/ipc/register/recording.ts so it does not clear the highlight on that
transition.

---

Nitpick comments:
In `@electron/native/ScreenCaptureKitWindowList.swift`:
- Around line 92-156: Add focused tests for the rectangle visibility math in
subtract and unionRect so the highlight bounds behavior is covered. Create
fixture cases for touching edges, full occlusion, nested occluders, and disjoint
visible regions, and assert the returned WindowRect pieces and merged bounds
match expectations. Keep the tests targeted around the existing
subtract(_:from:) and unionRect(_:) helpers so future changes to
ScreenCaptureKitWindowList remain safe.

In `@electron/sourceHighlightController.test.ts`:
- Around line 105-116: Update the source highlight controller clear-path test to
also verify the HUD passthrough reassertion side effect. In the
`createSourceHighlightController` setup, keep a spy for
`reassertHudOverlayMousePassthrough`, then in the `clear()` flow assert that
this callback is invoked in addition to `highlightWindow.close()` so the `clear`
lifecycle in `sourceHighlightController` is fully covered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6e15ff3f-390e-4aed-93f1-b16c81dd2eb7

📥 Commits

Reviewing files that changed from the base of the PR and between d8e34a1 and 3f6853e.

📒 Files selected for processing (22)
  • electron/electron-env.d.ts
  • electron/ipc/cursor/bounds.ts
  • electron/ipc/paths/binaries.ts
  • electron/ipc/register/recording.ts
  • electron/ipc/register/sources.ts
  • electron/ipc/types.ts
  • electron/main.ts
  • electron/native/ScreenCaptureKitWindowList.swift
  • electron/native/bin/darwin-arm64/recordly-window-list
  • electron/native/bin/darwin-x64/recordly-window-list
  • electron/preload.ts
  • electron/sourceHighlight.ts
  • electron/sourceHighlightController.test.ts
  • electron/sourceHighlightController.ts
  • src/components/launch/LaunchWindow.tsx
  • src/components/launch/SourceSelector.tsx
  • src/components/launch/hooks/useLaunchWindowActions.ts
  • src/components/launch/popovers/SourcePopover.tsx
  • src/components/launch/popovers/sourcePreviewRequestGate.test.ts
  • src/components/launch/popovers/sourcePreviewRequestGate.ts
  • src/components/video-editor/VideoPlayback.tsx
  • src/hooks/useScreenRecorder.ts
💤 Files with no reviewable changes (1)
  • src/components/video-editor/VideoPlayback.tsx

Comment thread electron/ipc/register/sources.ts Outdated
Comment thread src/components/launch/LaunchWindow.tsx
Comment thread src/components/launch/popovers/SourcePopover.tsx Outdated
webcamStartTime.current === null
? 0
: webcamStartTime.current - mainStartedAt;
showRecordingSourceHighlight(selectedSource, platform);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Re-show the highlight after the recording-start clear.

These calls happen before setRecordingState(true). Per the PR stack context, electron/ipc/register/recording.ts clears the source highlight when recording starts, so both flows can tear the overlay down immediately after you show it. Move the re-show until after the recording-start IPC settles, or stop clearing on that transition.

Also applies to: 1589-1597, 1929-1934

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/hooks/useScreenRecorder.ts` at line 1522, The recording source highlight
is being re-shown too early in the start-recording flow, so it gets cleared
again by the recording-start IPC transition. Update the relevant start paths in
useScreenRecorder (the selectedSource/platform highlight handling in both flows
noted in the review) to re-show the overlay only after the recording-start IPC
has settled, or adjust electron/ipc/register/recording.ts so it does not clear
the highlight on that transition.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
electron/native/ScreenCaptureKitWindowListGeometry.test.ts (1)

120-120: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Strict empty-output assertion can fail on benign swiftc warnings.

Asserting combined stdout+stderr equals "" makes any compiler warning (e.g. deprecations) a hard failure, conflating "no diagnostics" with "compiles successfully". Consider gating on exit status and only surfacing output when the status is non-zero.

♻️ Optional: assert on status, surface output on failure
-		expect([compile.stdout, compile.stderr].filter(Boolean).join("\n")).toBe("");
-		expect(compile.status).toBe(0);
+		expect(
+			compile.status,
+			[compile.stdout, compile.stderr].filter(Boolean).join("\n"),
+		).toBe(0);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@electron/native/ScreenCaptureKitWindowListGeometry.test.ts` at line 120, The
test in ScreenCaptureKitWindowListGeometry.test.ts is asserting that combined
swiftc stdout/stderr is exactly empty, which makes harmless compiler warnings
fail the test. Update the check around the compile result to rely on the process
exit status as the success condition, and only inspect or print the captured
output when the compile fails; use the existing compile result object in the
test to locate this assertion.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@electron/native/ScreenCaptureKitWindowListGeometry.test.ts`:
- Line 120: The test in ScreenCaptureKitWindowListGeometry.test.ts is asserting
that combined swiftc stdout/stderr is exactly empty, which makes harmless
compiler warnings fail the test. Update the check around the compile result to
rely on the process exit status as the success condition, and only inspect or
print the captured output when the compile fails; use the existing compile
result object in the test to locate this assertion.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 71145349-b236-46f4-81cd-0d2e5edf3f1b

📥 Commits

Reviewing files that changed from the base of the PR and between 3f6853e and 80f7463.

📒 Files selected for processing (5)
  • electron/ipc/register/sources.ts
  • electron/native/ScreenCaptureKitWindowListGeometry.test.ts
  • electron/sourceHighlightController.test.ts
  • src/components/launch/LaunchWindow.tsx
  • src/components/launch/popovers/SourcePopover.tsx
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/components/launch/popovers/SourcePopover.tsx
  • electron/sourceHighlightController.test.ts
  • src/components/launch/LaunchWindow.tsx

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

On selecting a target, render a highlighting border to identify window

1 participant