mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-24 23:05:49 +00:00
Merge pull request #321 from meiiie/fix/win10-floating-webcam-preview
fix(launch): disable floating webcam preview without passthrough
This commit is contained in:
Vendored
+4
@@ -88,6 +88,10 @@ interface Window {
|
||||
setHudOverlayCompactWidth: (width: number) => void;
|
||||
setHudOverlayMeasuredHeight: (height: number, expanded: boolean) => void;
|
||||
getHudOverlayCaptureProtection: () => Promise<{ success: boolean; enabled: boolean }>;
|
||||
getHudOverlayMousePassthroughSupported: () => Promise<{
|
||||
success: boolean;
|
||||
supported: boolean;
|
||||
}>;
|
||||
setHudOverlayCaptureProtection: (
|
||||
enabled: boolean,
|
||||
) => Promise<{ success: boolean; enabled: boolean }>;
|
||||
|
||||
@@ -96,6 +96,9 @@ contextBridge.exposeInMainWorld("electronAPI", {
|
||||
getHudOverlayCaptureProtection: () => {
|
||||
return ipcRenderer.invoke("get-hud-overlay-capture-protection");
|
||||
},
|
||||
getHudOverlayMousePassthroughSupported: () => {
|
||||
return ipcRenderer.invoke("get-hud-overlay-mouse-passthrough-supported");
|
||||
},
|
||||
setHudOverlayCaptureProtection: (enabled: boolean) => {
|
||||
return ipcRenderer.invoke("set-hud-overlay-capture-protection", enabled);
|
||||
},
|
||||
|
||||
@@ -413,6 +413,13 @@ ipcMain.handle("get-hud-overlay-capture-protection", () => {
|
||||
};
|
||||
});
|
||||
|
||||
ipcMain.handle("get-hud-overlay-mouse-passthrough-supported", () => {
|
||||
return {
|
||||
success: true,
|
||||
supported: isHudOverlayMousePassthroughSupported(),
|
||||
};
|
||||
});
|
||||
|
||||
ipcMain.handle("set-hud-overlay-capture-protection", (_event, enabled: boolean) => {
|
||||
loadHudOverlayCaptureProtectionSetting();
|
||||
hudOverlayHiddenFromCapture = Boolean(enabled);
|
||||
|
||||
@@ -41,6 +41,10 @@ import { ContentClamp } from "../ui/content-clamp";
|
||||
import ProjectBrowserDialog, {
|
||||
type ProjectLibraryEntry,
|
||||
} from "../video-editor/ProjectBrowserDialog";
|
||||
import {
|
||||
canShowFloatingWebcamPreview,
|
||||
canToggleFloatingWebcamPreview,
|
||||
} from "./floatingWebcamPreview";
|
||||
import {
|
||||
mergeHudInteractiveBounds,
|
||||
shouldRestoreHudMousePassthroughAfterDrag,
|
||||
@@ -199,6 +203,9 @@ export function LaunchWindow() {
|
||||
const [showFloatingWebcamPreview, setShowFloatingWebcamPreview] = useState(true);
|
||||
const [webcamPreviewOffset, setWebcamPreviewOffset] = useState(DEFAULT_WEBCAM_PREVIEW_OFFSET);
|
||||
const [recordingHudOffset, setRecordingHudOffset] = useState(DEFAULT_RECORDING_HUD_OFFSET);
|
||||
const [hudOverlayMousePassthroughSupported, setHudOverlayMousePassthroughSupported] = useState<
|
||||
boolean | null
|
||||
>(null);
|
||||
const [platform, setPlatform] = useState<string | null>(null);
|
||||
const [appVersion, setAppVersion] = useState<string | null>(null);
|
||||
const [updateStatus, setUpdateStatus] = useState<{
|
||||
@@ -264,9 +271,14 @@ export function LaunchWindow() {
|
||||
const micDropdownOpen = activeDropdown === "mic";
|
||||
const webcamDropdownOpen = activeDropdown === "webcam";
|
||||
const showWebcamControls = webcamEnabled && !recording;
|
||||
const showRecordingWebcamPreview = webcamEnabled && showFloatingWebcamPreview;
|
||||
const showRecordingWebcamPreview =
|
||||
webcamEnabled &&
|
||||
canShowFloatingWebcamPreview(
|
||||
showFloatingWebcamPreview,
|
||||
hudOverlayMousePassthroughSupported,
|
||||
);
|
||||
const shouldStreamWebcamPreview =
|
||||
webcamEnabled && (showFloatingWebcamPreview || (showWebcamControls && webcamDropdownOpen));
|
||||
webcamEnabled && (showRecordingWebcamPreview || (showWebcamControls && webcamDropdownOpen));
|
||||
const { devices, selectedDeviceId, setSelectedDeviceId } = useMicrophoneDevices(
|
||||
microphoneEnabled || micDropdownOpen,
|
||||
microphoneDeviceId,
|
||||
@@ -680,6 +692,24 @@ export function LaunchWindow() {
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
const loadHudOverlayMousePassthroughSupport = async () => {
|
||||
try {
|
||||
const result = await window.electronAPI.getHudOverlayMousePassthroughSupported();
|
||||
if (!cancelled && result.success) {
|
||||
setHudOverlayMousePassthroughSupported(result.supported);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to load HUD overlay mouse passthrough support:", error);
|
||||
}
|
||||
};
|
||||
void loadHudOverlayMousePassthroughSupport();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
void preparePermissions({ startup: true });
|
||||
}, [preparePermissions]);
|
||||
@@ -1403,25 +1433,29 @@ export function LaunchWindow() {
|
||||
>
|
||||
{t("recording.turnOffWebcam")}
|
||||
</DropdownItem>
|
||||
<DropdownItem
|
||||
icon={
|
||||
showFloatingWebcamPreview ? (
|
||||
<EyeOff size={16} />
|
||||
) : (
|
||||
<Eye size={16} />
|
||||
)
|
||||
}
|
||||
selected={showFloatingWebcamPreview}
|
||||
onClick={() => {
|
||||
setShowFloatingWebcamPreview(
|
||||
(current) => !current,
|
||||
);
|
||||
}}
|
||||
>
|
||||
{showFloatingWebcamPreview
|
||||
? t("recording.hideFloatingWebcamPreview")
|
||||
: t("recording.showFloatingWebcamPreview")}
|
||||
</DropdownItem>
|
||||
{canToggleFloatingWebcamPreview(
|
||||
hudOverlayMousePassthroughSupported,
|
||||
) ? (
|
||||
<DropdownItem
|
||||
icon={
|
||||
showFloatingWebcamPreview ? (
|
||||
<EyeOff size={16} />
|
||||
) : (
|
||||
<Eye size={16} />
|
||||
)
|
||||
}
|
||||
selected={showFloatingWebcamPreview}
|
||||
onClick={() => {
|
||||
setShowFloatingWebcamPreview(
|
||||
(current) => !current,
|
||||
);
|
||||
}}
|
||||
>
|
||||
{showFloatingWebcamPreview
|
||||
? t("recording.hideFloatingWebcamPreview")
|
||||
: t("recording.showFloatingWebcamPreview")}
|
||||
</DropdownItem>
|
||||
) : null}
|
||||
</>
|
||||
)}
|
||||
{!webcamEnabled && (
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import {
|
||||
canShowFloatingWebcamPreview,
|
||||
canToggleFloatingWebcamPreview,
|
||||
} from "./floatingWebcamPreview";
|
||||
|
||||
describe("canShowFloatingWebcamPreview", () => {
|
||||
it("shows the floating preview only when it was requested and passthrough is supported", () => {
|
||||
expect(canShowFloatingWebcamPreview(true, true)).toBe(true);
|
||||
expect(canShowFloatingWebcamPreview(false, true)).toBe(false);
|
||||
expect(canShowFloatingWebcamPreview(true, false)).toBe(false);
|
||||
expect(canShowFloatingWebcamPreview(true, null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("canToggleFloatingWebcamPreview", () => {
|
||||
it("keeps the toggle visible while support is unknown or available", () => {
|
||||
expect(canToggleFloatingWebcamPreview(null)).toBe(true);
|
||||
expect(canToggleFloatingWebcamPreview(true)).toBe(true);
|
||||
});
|
||||
|
||||
it("hides the toggle when the platform cannot support the floating preview", () => {
|
||||
expect(canToggleFloatingWebcamPreview(false)).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
export function canShowFloatingWebcamPreview(
|
||||
requested: boolean,
|
||||
hudOverlayMousePassthroughSupported: boolean | null,
|
||||
): boolean {
|
||||
return requested && hudOverlayMousePassthroughSupported === true;
|
||||
}
|
||||
|
||||
export function canToggleFloatingWebcamPreview(
|
||||
hudOverlayMousePassthroughSupported: boolean | null,
|
||||
): boolean {
|
||||
return hudOverlayMousePassthroughSupported !== false;
|
||||
}
|
||||
Reference in New Issue
Block a user