From 865ae26df5b75ad02a94a7137e922d71578b66cf Mon Sep 17 00:00:00 2001 From: ai-linor Date: Wed, 13 May 2026 16:16:16 +0530 Subject: [PATCH 1/3] fix(mac): fix Safari rendering black/white when using window capture --- electron/native/ScreenCaptureKitRecorder.swift | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/electron/native/ScreenCaptureKitRecorder.swift b/electron/native/ScreenCaptureKitRecorder.swift index c5cd8fabf..40f828352 100644 --- a/electron/native/ScreenCaptureKitRecorder.swift +++ b/electron/native/ScreenCaptureKitRecorder.swift @@ -107,12 +107,17 @@ final class ScreenCaptureRecorder: NSObject, SCStreamOutput, SCStreamDelegate { throw NSError(domain: "RecordlyCapture", code: 3, userInfo: [NSLocalizedDescriptionKey: "Window not found"]) } - filter = SCContentFilter(desktopIndependentWindow: window) - let candidateDisplay = availableContent.displays.first(where: { $0.frame.intersects(window.frame) || $0.frame.contains(CGPoint(x: window.frame.midX, y: window.frame.midY)) - }) - let scaleFactor = ScreenCaptureRecorder.scaleFactor(for: candidateDisplay?.displayID ?? CGMainDisplayID()) + }) ?? availableContent.displays.first + + guard let display = candidateDisplay else { + throw NSError(domain: "RecordlyCapture", code: 4, userInfo: [NSLocalizedDescriptionKey: "No display found for window"]) + } + + filter = SCContentFilter(display: display, including: [window], exceptingApplications: [], exceptingWindows: []) + + let scaleFactor = ScreenCaptureRecorder.scaleFactor(for: display.displayID) outputWidth = max(2, Int(window.frame.width) * scaleFactor) outputHeight = max(2, Int(window.frame.height) * scaleFactor) if #available(macOS 14.0, *) { From 1476ed7a585f5a1fe1e59fa91639a6d99f529879 Mon Sep 17 00:00:00 2001 From: ai-linor Date: Wed, 13 May 2026 16:40:48 +0530 Subject: [PATCH 2/3] fix(editor): prevent buggy frame extensions from crashing the entire video preview --- src/components/video-editor/VideoPlayback.tsx | 35 +++++++++++-------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/components/video-editor/VideoPlayback.tsx b/src/components/video-editor/VideoPlayback.tsx index c64e6b425..f1048bc71 100644 --- a/src/components/video-editor/VideoPlayback.tsx +++ b/src/components/video-editor/VideoPlayback.tsx @@ -1097,20 +1097,24 @@ const VideoPlayback = forwardRef( if (!frameData) return false; if (frameData.draw) { - // Resolution-independent: draw at a reasonable size, Pixi handles the rest - const drawW = 1920; - const drawH = 1080; - const canvas = document.createElement("canvas"); - canvas.width = drawW; - canvas.height = drawH; - const ctx = canvas.getContext("2d"); - if (ctx) frameData.draw(ctx, drawW, drawH); - if (cancelled || frameIdRef.current !== frame) return true; - const texture = Texture.from(canvas); - const sprite = new Sprite(texture); - frameSpriteRef.current = sprite; - container.addChild(sprite); - layoutVideoContentRef.current?.(); + try { + // Resolution-independent: draw at a reasonable size, Pixi handles the rest + const drawW = 1920; + const drawH = 1080; + const canvas = document.createElement("canvas"); + canvas.width = drawW; + canvas.height = drawH; + const ctx = canvas.getContext("2d"); + if (ctx) frameData.draw(ctx, drawW, drawH); + if (cancelled || frameIdRef.current !== frame) return true; + const texture = Texture.from(canvas); + const sprite = new Sprite(texture); + frameSpriteRef.current = sprite; + container.addChild(sprite); + layoutVideoContentRef.current?.(); + } catch (err) { + console.error(`[VideoPlayback] Failed to draw frame '${frameData.id}':`, err); + } } else { const img = new Image(); img.onload = () => { @@ -1121,6 +1125,9 @@ const VideoPlayback = forwardRef( container.addChild(sprite); layoutVideoContentRef.current?.(); }; + img.onerror = (err) => { + console.error(`[VideoPlayback] Failed to load frame image from '${frameData.filePath}':`, err); + }; img.src = frameData.filePath; } return true; From d7999ef895af8cc6fef431ec7887fa4068e0e366 Mon Sep 17 00:00:00 2001 From: ai-linor Date: Wed, 13 May 2026 17:14:43 +0530 Subject: [PATCH 3/3] fix(mac): address coderabbit review feedback on capture display resolution --- electron/native/ScreenCaptureKitRecorder.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/electron/native/ScreenCaptureKitRecorder.swift b/electron/native/ScreenCaptureKitRecorder.swift index 40f828352..d8757f03b 100644 --- a/electron/native/ScreenCaptureKitRecorder.swift +++ b/electron/native/ScreenCaptureKitRecorder.swift @@ -109,10 +109,10 @@ final class ScreenCaptureRecorder: NSObject, SCStreamOutput, SCStreamDelegate { let candidateDisplay = availableContent.displays.first(where: { $0.frame.intersects(window.frame) || $0.frame.contains(CGPoint(x: window.frame.midX, y: window.frame.midY)) - }) ?? availableContent.displays.first + }) guard let display = candidateDisplay else { - throw NSError(domain: "RecordlyCapture", code: 4, userInfo: [NSLocalizedDescriptionKey: "No display found for window"]) + throw NSError(domain: "RecordlyCapture", code: 4, userInfo: [NSLocalizedDescriptionKey: "No intersecting display found for window"]) } filter = SCContentFilter(display: display, including: [window], exceptingApplications: [], exceptingWindows: []) @@ -660,8 +660,8 @@ guard CommandLine.arguments.count >= 2 else { } // Force CoreGraphics Services initialization on the main thread. -// Without this, SCContentFilter(desktopIndependentWindow:) crashes with -// CGS_REQUIRE_INIT because CGS is never initialised in a CLI tool. +// Without this, CoreGraphics operations may fail with CGS_REQUIRE_INIT +// because CGS is never initialised in a CLI tool. let _ = CGMainDisplayID() // Pre-flight check: ensure screen recording permission is granted before