From cbde700ab7c9ef122a80cfeb067f0940d51d3cf1 Mon Sep 17 00:00:00 2001 From: webadderall <131426131+webadderall@users.noreply.github.com> Date: Sun, 29 Mar 2026 13:13:15 +1100 Subject: [PATCH] fix video editor not opening sometimes in prod --- electron/ipc/handlers.ts | 49 ++++++++++++++++++++++++++++++---- electron/windows.ts | 23 ++++++++++++++++ src/hooks/useScreenRecorder.ts | 42 +++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 5 deletions(-) diff --git a/electron/ipc/handlers.ts b/electron/ipc/handlers.ts index a793bda5..b06969dc 100644 --- a/electron/ipc/handlers.ts +++ b/electron/ipc/handlers.ts @@ -2612,6 +2612,27 @@ async function finalizeStoredVideo(videoPath: string) { await pruneAutoRecordings([videoPath]) } + if (lastNativeCaptureDiagnostics?.backend === 'mac-screencapturekit') { + recordNativeCaptureDiagnostics({ + backend: 'mac-screencapturekit', + phase: 'stop', + sourceId: lastNativeCaptureDiagnostics.sourceId ?? null, + sourceType: lastNativeCaptureDiagnostics.sourceType ?? 'unknown', + displayId: lastNativeCaptureDiagnostics.displayId ?? null, + displayBounds: lastNativeCaptureDiagnostics.displayBounds ?? null, + windowHandle: lastNativeCaptureDiagnostics.windowHandle ?? null, + helperPath: lastNativeCaptureDiagnostics.helperPath ?? null, + outputPath: videoPath, + systemAudioPath: lastNativeCaptureDiagnostics.systemAudioPath ?? null, + microphonePath: lastNativeCaptureDiagnostics.microphonePath ?? null, + osRelease: lastNativeCaptureDiagnostics.osRelease, + supported: lastNativeCaptureDiagnostics.supported, + helperExists: lastNativeCaptureDiagnostics.helperExists, + processOutput: lastNativeCaptureDiagnostics.processOutput, + fileSizeBytes: validation.fileSizeBytes, + }) + } + return { success: true, path: videoPath, @@ -2771,7 +2792,7 @@ async function startInteractionCapture() { export function registerIpcHandlers( createEditorWindow: () => void, createSourceSelectorWindow: () => BrowserWindow, - getMainWindow: () => BrowserWindow | null, + _getMainWindow: () => BrowserWindow | null, getSourceSelectorWindow: () => BrowserWindow | null, onRecordingStateChange?: (recording: boolean, sourceName: string) => void ) { @@ -3148,10 +3169,7 @@ body{background:transparent;overflow:hidden;width:100vw;height:100vh} }) ipcMain.handle('switch-to-editor', () => { - const mainWin = getMainWindow() - if (mainWin) { - mainWin.close() - } + console.log('[switch-to-editor] Opening editor window') createEditorWindow() }) @@ -3585,6 +3603,7 @@ body{background:transparent;overflow:hidden;width:100vw;height:100vh} const fallbackPath = nativeCaptureTargetPath const fallbackSystemAudioPath = nativeCaptureSystemAudioPath const fallbackMicrophonePath = nativeCaptureMicrophonePath + const fallbackFileSizeBytes = await getFileSizeIfPresent(fallbackPath) nativeScreenRecordingActive = false nativeCaptureProcess = null nativeCaptureTargetPath = null @@ -3593,6 +3612,26 @@ body{background:transparent;overflow:hidden;width:100vw;height:100vh} nativeCaptureStopRequested = false nativeCapturePaused = false + recordNativeCaptureDiagnostics({ + backend: 'mac-screencapturekit', + phase: 'stop', + sourceId: lastNativeCaptureDiagnostics?.sourceId ?? null, + sourceType: lastNativeCaptureDiagnostics?.sourceType ?? 'unknown', + displayId: lastNativeCaptureDiagnostics?.displayId ?? null, + displayBounds: lastNativeCaptureDiagnostics?.displayBounds ?? null, + windowHandle: lastNativeCaptureDiagnostics?.windowHandle ?? null, + helperPath: lastNativeCaptureDiagnostics?.helperPath ?? null, + outputPath: fallbackPath, + systemAudioPath: fallbackSystemAudioPath, + microphonePath: fallbackMicrophonePath, + osRelease: lastNativeCaptureDiagnostics?.osRelease, + supported: lastNativeCaptureDiagnostics?.supported, + helperExists: lastNativeCaptureDiagnostics?.helperExists, + processOutput: nativeCaptureOutputBuffer.trim() || undefined, + fileSizeBytes: fallbackFileSizeBytes, + error: String(error), + }) + // Try to recover: if the target file exists on disk, finalize with it if (fallbackPath) { try { diff --git a/electron/windows.ts b/electron/windows.ts index 16a619da..ddcaf5d6 100644 --- a/electron/windows.ts +++ b/electron/windows.ts @@ -435,16 +435,39 @@ export function createEditorWindow(): BrowserWindow { }); win.once("ready-to-show", () => { + console.log("[editor-window] ready-to-show"); win.show(); }); win.webContents.on("did-finish-load", () => { + console.log("[editor-window] did-finish-load", win.webContents.getURL()); win?.webContents.send("main-process-message", new Date().toLocaleString()); }); + win.webContents.on("did-fail-load", (_event, errorCode, errorDescription, validatedURL) => { + console.error("[editor-window] did-fail-load", { + errorCode, + errorDescription, + validatedURL, + }); + }); + + win.webContents.on("render-process-gone", (_event, details) => { + console.error("[editor-window] render-process-gone", details); + }); + + win.on("show", () => { + console.log("[editor-window] show"); + }); + + win.on("focus", () => { + console.log("[editor-window] focus"); + }); + if (VITE_DEV_SERVER_URL) { win.loadURL(VITE_DEV_SERVER_URL + "?windowType=editor"); } else { + console.log("[editor-window] load-file", path.join(RENDERER_DIST, "index.html")); win.loadFile(path.join(RENDERER_DIST, "index.html"), { query: { windowType: "editor" }, }); diff --git a/src/hooks/useScreenRecorder.ts b/src/hooks/useScreenRecorder.ts index 932f2c6a..3777dbe7 100644 --- a/src/hooks/useScreenRecorder.ts +++ b/src/hooks/useScreenRecorder.ts @@ -110,6 +110,40 @@ export function useScreenRecorder(): UseScreenRecorderReturn { } }, []); + const buildNativeCaptureFailureMessage = useCallback( + async (context: string, fallbackMessage: string) => { + if (typeof window.electronAPI?.getLastNativeCaptureDiagnostics !== "function") { + return fallbackMessage; + } + + try { + const result = await window.electronAPI.getLastNativeCaptureDiagnostics(); + const diagnostics = result.success ? result.diagnostics ?? null : null; + if (!diagnostics) { + return fallbackMessage; + } + + console.warn(`[NativeCaptureDiagnostics:${context}]`, diagnostics); + + const details: string[] = []; + if (diagnostics.error) { + details.push(diagnostics.error); + } + if (diagnostics.outputPath) { + details.push(`Saved file: ${diagnostics.outputPath}`); + } + + return details.length > 0 + ? `${fallbackMessage} ${details.join(". ")}` + : fallbackMessage; + } catch (error) { + console.warn("Failed to load native capture diagnostics:", error); + return fallbackMessage; + } + }, + [], + ); + const resetRecordingClock = useCallback((startedAt: number) => { startTime.current = startedAt; accumulatedPausedDurationMs.current = 0; @@ -458,6 +492,14 @@ export function useScreenRecorder(): UseScreenRecorderReturn { } catch (recoveryError) { console.error("Failed to recover native screen recording:", recoveryError); } + + const failureMessage = await buildNativeCaptureFailureMessage( + "stop-native-screen-recording", + isMacOS + ? "Failed to finish the macOS recording, so the editor was not opened." + : "Failed to finish the recording, so the editor was not opened.", + ); + toast.error(failureMessage, { duration: 10000 }); return; }