Skip to content

Revert HUD passthrough and Linux fallback changes#656

Merged
webadderall merged 6 commits into
mainfrom
revert/hud-linux-fallback-fixes
Jun 6, 2026
Merged

Revert HUD passthrough and Linux fallback changes#656
webadderall merged 6 commits into
mainfrom
revert/hud-linux-fallback-fixes

Conversation

@webadderall
Copy link
Copy Markdown
Collaborator

@webadderall webadderall commented Jun 5, 2026

Summary

  • revert the Windows HUD passthrough regressions introduced after v1.3.1
  • revert the Linux HUD/capture fallback changes that destabilized the older behavior
  • keep the branch focused on the existing revert commits already on top of main

Validation

  • npm exec -- vitest run electron/hudOverlayBounds.test.ts src/hooks/useScreenRecorder.test.ts
  • npm exec -- vitest run src/components/video-editor/videoPlayback/zoomAnimation.test.ts

Summary by CodeRabbit

  • Improvements

    • Always-available cursor controls and simplified cursor behavior.
    • More responsive HUD mouse interactions using hover-driven handling.
    • Simplified OS-cursor hide response (now returns a consistent success result).
  • Removed

    • HUD webcam-preview visibility control exposed to the renderer (overlay preview no longer synchronized).
    • Several helper predicates related to Linux/source mapping and HUD fallback logic.
  • Tests

    • Some internal tests for source mapping and HUD fallbacks were removed.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 5, 2026

Worried about impact? Review this PR in Change Stack to explore blast radius before you approve or request changes.

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 85320dc6-54c1-446d-9660-93787061e6e1

📥 Commits

Reviewing files that changed from the base of the PR and between 489e3ca and e99356a.

📒 Files selected for processing (3)
  • electron/ipc/register/sourceMapping.test.ts
  • electron/ipc/register/sourceMapping.ts
  • electron/ipc/register/sources.ts
✅ Files skipped from review due to trivial changes (1)
  • electron/ipc/register/sources.ts

📝 Walkthrough

Walkthrough

Removes nativeCaptureUnavailable session metadata and HUD webcam-preview sync, deletes source-mapping helpers, inlines Linux-portal sentinel logic, simplifies HUD mouse passthrough APIs, and updates recorder/editor flows and tests to match the reduced session/API shapes.

Changes

Feature removal: nativeCaptureUnavailable, webcam HUD sync, and source mapping simplification

Layer / File(s) Summary
Type contract cleanup
electron/electron-env.d.ts, electron/ipc/types.ts, electron/preload.ts
Removes nativeCaptureUnavailable?: boolean from renderer API and IPC types; simplifies hideOsCursor() return to { success: boolean }; removes hudOverlaySetWebcamPreviewVisible from preload electronAPI bridge.
IPC handler and session contract updates
electron/ipc/register/project.ts, electron/ipc/register/settings.ts
set-current-video-path and set-current-recording-session handlers stop accepting/propagating nativeCaptureUnavailable; hide-cursor handler returns { success: true } on non-Windows platforms.
Linux portal source mapping removal
electron/ipc/register/sourceMapping.ts, electron/ipc/register/sources.ts, electron/main.ts, electron/ipc/register/sourceMapping.test.ts
Deletes source-mapping helpers and related tests; sources.ts and main.ts now use literal/inline checks ("screen:linux-portal" / falsy sourceId) for portal routing and sentinel detection.
HUD bounds and webcam preview removal
electron/hudOverlayBounds.ts, electron/hudOverlayBounds.test.ts, electron/windows.ts, src/components/launch/LaunchWindow.tsx
Removes fallback resize/expand predicate helpers and their tests; drops hudOverlayWebcamPreviewVisible state and IPC listener; getHudOverlayBounds() uses fallback-expanded state directly; LaunchWindow stops syncing webcam preview to HUD.
Mouse passthrough and HUD interaction refactoring
electron/windows.ts, src/components/launch/hooks/useLaunchHudInteractionState.ts
Refactors non-passthrough-supported flow, changes reassertHudOverlayMousePassthrough() to a zero-arg function with fixed 50ms delay, and replaces throttled reassert with hover-driven mouseover handling in the HUD interaction hook.
Recording session finalization and browser capture simplification
src/hooks/useScreenRecorder.ts, src/hooks/useScreenRecorder.test.ts, src/components/video-editor/*
Removes nativeCaptureUnavailable from BrowserCaptureCursorPolicy and from all session/video persistence calls; deletes Linux-portal helper exports and simplifies portal routing to id checks; updates tests and UI (SettingsPanel/VideoEditor) to remove cursor-unavailable gating and modal paths.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

Checked

"I hopped through code with tiny paws,
Trimmed old flags and cleaned the laws,
Portal checks inlined, webcam links undone,
HUD now listens when the mouse has fun,
A rabbit's nibble made the paths more run." 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% 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
Title check ✅ Passed The title accurately describes the main change: reverting HUD passthrough and Linux fallback changes across multiple files.
Description check ✅ Passed The description provides a clear summary and validation steps, but lacks several template sections like Type of Change, Related Issue(s), Screenshots/Video, Testing Guide details, and Checklist.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch revert/hud-linux-fallback-fixes

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/launch/hooks/useLaunchHudInteractionState.ts (1)

42-55: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep the HUD interactive while a popover is open.

On Line 45 and Line 84, the ignore-mouse timers still arm even when openId is non-null. That lets an already-open HUD menu/popover flip the overlay back to click-through mid-interaction.

Suggested fix
 		if (isInteractive) {
 			isMouseOverHudRef.current = true;
 			if (timeoutRef.current) clearTimeout(timeoutRef.current);
 			window.electronAPI?.hudOverlaySetIgnoreMouse?.(false);
-		} else {
+		} else if (openId === null) {
 			isMouseOverHudRef.current = false;
 			if (timeoutRef.current) clearTimeout(timeoutRef.current);
 			timeoutRef.current = setTimeout(() => {
 				if (
+					openId === null &&
 					!isHudDraggingRef.current &&
 					!isWebcamPreviewDraggingRef.current &&
 					!webcamPreviewDragStartRef.current &&
 					!isMouseOverHudRef.current
 				) {
 					window.electronAPI?.hudOverlaySetIgnoreMouse?.(true);
 				}
 			}, 300);
 		}
 	};

 	window.addEventListener("mouseover", handleMouseOver);
 	return () => window.removeEventListener("mouseover", handleMouseOver);
-	}, [isHudDraggingRef, isWebcamPreviewDraggingRef, webcamPreviewDragStartRef]);
+	}, [openId, isHudDraggingRef, isWebcamPreviewDraggingRef, webcamPreviewDragStartRef]);
...
 			timeoutRef.current = setTimeout(() => {
 				if (
+					openId === null &&
 					!isHudDraggingRef.current &&
 					!isWebcamPreviewDraggingRef.current &&
 					!webcamPreviewDragStartRef.current &&
 					!isMouseOverHudRef.current
 				) {
 					window.electronAPI?.hudOverlaySetIgnoreMouse?.(true);
 				}
 			}, 300);
 		},
-		[isHudDraggingRef, isWebcamPreviewDraggingRef, webcamPreviewDragStartRef],
+		[openId, isHudDraggingRef, isWebcamPreviewDraggingRef, webcamPreviewDragStartRef],
 	);

Also applies to: 84-93

🤖 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/components/launch/hooks/useLaunchHudInteractionState.ts` around lines 42
- 55, The timer callback that sets window.electronAPI.hudOverlaySetIgnoreMouse
is firing even when a HUD popover/menu is open; update the logic in the hook
(the blocks using isMouseOverHudRef, timeoutRef and setTimeout) to first check
that openId is null/undefined before arming or executing the timeout callback —
i.e., include a guard referencing openId (from the hook state/params) both
before scheduling timeoutRef.current = setTimeout(...) and inside the timeout
callback so that when openId is non-null the overlay is not switched to
ignore-mouse; apply the same change to the second occurrence that uses
isHudDraggingRef, isWebcamPreviewDraggingRef and webcamPreviewDragStartRef so
popovers remain interactive.
🤖 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 127-129: Restore the Linux portal sentinel mapping when returning
screen rows from register/sources.ts: instead of emitting matchedSource?.id or
`screen:fallback:${displayId}` directly, map portal-like identifiers back to the
sentinel "screen:linux-portal" (or call the previous helper such as
normalizeScreenId or mapSourceToSentinel) so that after explicit selection
useScreenRecorder.ts still sees the portal-safe id; ensure both the
matchedSource present branch and the fallback branch normalize to the sentinel
when appropriate and keep the displayName unchanged.

---

Outside diff comments:
In `@src/components/launch/hooks/useLaunchHudInteractionState.ts`:
- Around line 42-55: The timer callback that sets
window.electronAPI.hudOverlaySetIgnoreMouse is firing even when a HUD
popover/menu is open; update the logic in the hook (the blocks using
isMouseOverHudRef, timeoutRef and setTimeout) to first check that openId is
null/undefined before arming or executing the timeout callback — i.e., include a
guard referencing openId (from the hook state/params) both before scheduling
timeoutRef.current = setTimeout(...) and inside the timeout callback so that
when openId is non-null the overlay is not switched to ignore-mouse; apply the
same change to the second occurrence that uses isHudDraggingRef,
isWebcamPreviewDraggingRef and webcamPreviewDragStartRef so popovers remain
interactive.
🪄 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: bddacc97-8290-4cb9-b3b1-d3556cbaedc5

📥 Commits

Reviewing files that changed from the base of the PR and between 375620b and 1804191.

📒 Files selected for processing (18)
  • electron/electron-env.d.ts
  • electron/hudOverlayBounds.test.ts
  • electron/hudOverlayBounds.ts
  • electron/ipc/register/project.ts
  • electron/ipc/register/settings.ts
  • electron/ipc/register/sourceMapping.test.ts
  • electron/ipc/register/sourceMapping.ts
  • electron/ipc/register/sources.ts
  • electron/ipc/types.ts
  • electron/main.ts
  • electron/preload.ts
  • electron/windows.ts
  • src/components/launch/LaunchWindow.tsx
  • src/components/launch/hooks/useLaunchHudInteractionState.ts
  • src/components/video-editor/SettingsPanel.tsx
  • src/components/video-editor/VideoEditor.tsx
  • src/hooks/useScreenRecorder.test.ts
  • src/hooks/useScreenRecorder.ts
💤 Files with no reviewable changes (9)
  • electron/ipc/register/sourceMapping.ts
  • electron/ipc/register/sourceMapping.test.ts
  • electron/ipc/types.ts
  • src/components/launch/LaunchWindow.tsx
  • electron/hudOverlayBounds.ts
  • electron/hudOverlayBounds.test.ts
  • src/components/video-editor/SettingsPanel.tsx
  • electron/preload.ts
  • src/hooks/useScreenRecorder.test.ts

Comment thread electron/ipc/register/sources.ts
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
electron/ipc/register/sourceMapping.test.ts (1)

19-49: ⚡ Quick win

Cover the WAYLAND_DISPLAY-only Wayland path.

isLikelyLinuxWaylandSession() has a distinct fallback branch for environments where XDG_SESSION_TYPE is unset, but this suite never exercises it. A regression there would silently flip those Linux sessions back to screen:fallback:*.

Suggested test
 describe("getScreenSourceIdForDisplay", () => {
 	it("keeps the live Electron screen source when one is available", () => {
 		expect(
 			getScreenSourceIdForDisplay({
 				displayId: "42",
 				matchedSourceId: "screen:42:0",
 				platform: "linux",
 			}),
 		).toBe("screen:42:0");
 	});
 
 	it("routes unmatched Linux Wayland screens through the portal sentinel", () => {
 		expect(
 			getScreenSourceIdForDisplay({
 				displayId: "42",
 				env: { XDG_SESSION_TYPE: "wayland", WAYLAND_DISPLAY: "wayland-0" },
 				matchedSourceId: null,
 				platform: "linux",
 			}),
 		).toBe(LINUX_PORTAL_SCREEN_SOURCE_ID);
 	});
+
+	it("treats WAYLAND_DISPLAY without XDG_SESSION_TYPE as Wayland", () => {
+		expect(
+			getScreenSourceIdForDisplay({
+				displayId: "42",
+				env: { WAYLAND_DISPLAY: "wayland-0" },
+				matchedSourceId: null,
+				platform: "linux",
+			}),
+		).toBe(LINUX_PORTAL_SCREEN_SOURCE_ID);
+	});
 
 	it("keeps unmatched Linux X11 screens on the explicit fallback id", () => {
 		expect(
 			getScreenSourceIdForDisplay({
 				displayId: "42",
🤖 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/ipc/register/sourceMapping.test.ts` around lines 19 - 49, Add a test
that exercises the codepath where XDG_SESSION_TYPE is unset but WAYLAND_DISPLAY
is present: call getScreenSourceIdForDisplay with platform "linux", displayId
"42", env: { WAYLAND_DISPLAY: "wayland-0" } (no XDG_SESSION_TYPE), and
matchedSourceId null/undefined, and assert it returns
LINUX_PORTAL_SCREEN_SOURCE_ID so the isLikelyLinuxWaylandSession fallback is
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/sourceMapping.ts`:
- Around line 1-35: The code removed handling for legacy "screen:fallback:*"
ids; restore a small normalizer so legacy persisted Wayland selections are
treated as the portal alias. In getScreenSourceIdForDisplay check if
matchedSourceId startsWith("screen:fallback:") and map it to
LINUX_PORTAL_SCREEN_SOURCE_ID (or otherwise ensure the returned id signals the
portal branch) before the platform/env checks; also ensure the caller/handler in
electron/main.ts continues to branch on that normalized portal id rather than
running desktopCapturer.getSources() for legacy "screen:fallback:*" values.

---

Nitpick comments:
In `@electron/ipc/register/sourceMapping.test.ts`:
- Around line 19-49: Add a test that exercises the codepath where
XDG_SESSION_TYPE is unset but WAYLAND_DISPLAY is present: call
getScreenSourceIdForDisplay with platform "linux", displayId "42", env: {
WAYLAND_DISPLAY: "wayland-0" } (no XDG_SESSION_TYPE), and matchedSourceId
null/undefined, and assert it returns LINUX_PORTAL_SCREEN_SOURCE_ID so the
isLikelyLinuxWaylandSession fallback is 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: 85320dc6-54c1-446d-9660-93787061e6e1

📥 Commits

Reviewing files that changed from the base of the PR and between 489e3ca and e99356a.

📒 Files selected for processing (3)
  • electron/ipc/register/sourceMapping.test.ts
  • electron/ipc/register/sourceMapping.ts
  • electron/ipc/register/sources.ts
✅ Files skipped from review due to trivial changes (1)
  • electron/ipc/register/sources.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

🧹 Nitpick comments (1)
electron/ipc/register/sourceMapping.test.ts (1)

19-49: ⚡ Quick win

Cover the WAYLAND_DISPLAY-only Wayland path.

isLikelyLinuxWaylandSession() has a distinct fallback branch for environments where XDG_SESSION_TYPE is unset, but this suite never exercises it. A regression there would silently flip those Linux sessions back to screen:fallback:*.

Suggested test
 describe("getScreenSourceIdForDisplay", () => {
 	it("keeps the live Electron screen source when one is available", () => {
 		expect(
 			getScreenSourceIdForDisplay({
 				displayId: "42",
 				matchedSourceId: "screen:42:0",
 				platform: "linux",
 			}),
 		).toBe("screen:42:0");
 	});
 
 	it("routes unmatched Linux Wayland screens through the portal sentinel", () => {
 		expect(
 			getScreenSourceIdForDisplay({
 				displayId: "42",
 				env: { XDG_SESSION_TYPE: "wayland", WAYLAND_DISPLAY: "wayland-0" },
 				matchedSourceId: null,
 				platform: "linux",
 			}),
 		).toBe(LINUX_PORTAL_SCREEN_SOURCE_ID);
 	});
+
+	it("treats WAYLAND_DISPLAY without XDG_SESSION_TYPE as Wayland", () => {
+		expect(
+			getScreenSourceIdForDisplay({
+				displayId: "42",
+				env: { WAYLAND_DISPLAY: "wayland-0" },
+				matchedSourceId: null,
+				platform: "linux",
+			}),
+		).toBe(LINUX_PORTAL_SCREEN_SOURCE_ID);
+	});
 
 	it("keeps unmatched Linux X11 screens on the explicit fallback id", () => {
 		expect(
 			getScreenSourceIdForDisplay({
 				displayId: "42",
🤖 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/ipc/register/sourceMapping.test.ts` around lines 19 - 49, Add a test
that exercises the codepath where XDG_SESSION_TYPE is unset but WAYLAND_DISPLAY
is present: call getScreenSourceIdForDisplay with platform "linux", displayId
"42", env: { WAYLAND_DISPLAY: "wayland-0" } (no XDG_SESSION_TYPE), and
matchedSourceId null/undefined, and assert it returns
LINUX_PORTAL_SCREEN_SOURCE_ID so the isLikelyLinuxWaylandSession fallback is
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/sourceMapping.ts`:
- Around line 1-35: The code removed handling for legacy "screen:fallback:*"
ids; restore a small normalizer so legacy persisted Wayland selections are
treated as the portal alias. In getScreenSourceIdForDisplay check if
matchedSourceId startsWith("screen:fallback:") and map it to
LINUX_PORTAL_SCREEN_SOURCE_ID (or otherwise ensure the returned id signals the
portal branch) before the platform/env checks; also ensure the caller/handler in
electron/main.ts continues to branch on that normalized portal id rather than
running desktopCapturer.getSources() for legacy "screen:fallback:*" values.

---

Nitpick comments:
In `@electron/ipc/register/sourceMapping.test.ts`:
- Around line 19-49: Add a test that exercises the codepath where
XDG_SESSION_TYPE is unset but WAYLAND_DISPLAY is present: call
getScreenSourceIdForDisplay with platform "linux", displayId "42", env: {
WAYLAND_DISPLAY: "wayland-0" } (no XDG_SESSION_TYPE), and matchedSourceId
null/undefined, and assert it returns LINUX_PORTAL_SCREEN_SOURCE_ID so the
isLikelyLinuxWaylandSession fallback is 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: 85320dc6-54c1-446d-9660-93787061e6e1

📥 Commits

Reviewing files that changed from the base of the PR and between 489e3ca and e99356a.

📒 Files selected for processing (3)
  • electron/ipc/register/sourceMapping.test.ts
  • electron/ipc/register/sourceMapping.ts
  • electron/ipc/register/sources.ts
✅ Files skipped from review due to trivial changes (1)
  • electron/ipc/register/sources.ts
🛑 Comments failed to post (1)
electron/ipc/register/sourceMapping.ts (1)

1-35: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep screen:fallback:* as a Linux/Wayland portal alias.

Removing the fallback-id predicate here drops the compatibility path for persisted Wayland selections. electron/main.ts now only takes the single-portal branch for screen:linux-portal or an empty source id, so an older session saved as screen:fallback:42 will go back through desktopCapturer.getSources() and reintroduce the extra portal flow this revert is trying to avoid. Please keep a small normalizer/predicate for legacy screen:fallback:* ids and continue branching on it in the handler.

🤖 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/ipc/register/sourceMapping.ts` around lines 1 - 35, The code removed
handling for legacy "screen:fallback:*" ids; restore a small normalizer so
legacy persisted Wayland selections are treated as the portal alias. In
getScreenSourceIdForDisplay check if matchedSourceId
startsWith("screen:fallback:") and map it to LINUX_PORTAL_SCREEN_SOURCE_ID (or
otherwise ensure the returned id signals the portal branch) before the
platform/env checks; also ensure the caller/handler in electron/main.ts
continues to branch on that normalized portal id rather than running
desktopCapturer.getSources() for legacy "screen:fallback:*" values.

@webadderall webadderall merged commit bfe0a2f into main Jun 6, 2026
3 checks passed
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.

1 participant