From a23a356ac2e6bbc7431a454a0a45a7e744d8641d Mon Sep 17 00:00:00 2001 From: Keath Milligan Date: Sun, 24 Aug 2025 15:33:51 -0500 Subject: [PATCH 1/2] Fix null pointer reference on MacOS Use ScreenCapturekit directly to get window dimensions. --- src/targets/mac/mod.rs | 62 +++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/src/targets/mac/mod.rs b/src/targets/mac/mod.rs index ed89008..a09ca68 100644 --- a/src/targets/mac/mod.rs +++ b/src/targets/mac/mod.rs @@ -86,13 +86,41 @@ pub fn get_main_display() -> Display { pub fn get_scale_factor(target: &Target) -> f64 { match target { - Target::Window(window) => unsafe { - let cg_win_id = window.raw_handle; - let ns_app: id = NSApp(); - let ns_window: id = msg_send![ns_app, windowWithWindowNumber: cg_win_id as NSUInteger]; - let scale_factor: f64 = msg_send![ns_window, backingScaleFactor]; - scale_factor - }, + Target::Window(window) => { + // Get the window's frame to determine which display it's on + let content = block_on(sc::ShareableContent::current()).unwrap(); + + // Find the window in ScreenCaptureKit + if let Some(sc_window) = content + .windows() + .iter() + .find(|w| w.id() == window.raw_handle) + { + let window_frame = sc_window.frame(); + let window_center_x = window_frame.origin.x + window_frame.size.width / 2.0; + let window_center_y = window_frame.origin.y + window_frame.size.height / 2.0; + + // Find which display contains the center of the window + for display in content.displays().iter() { + let display_id = display.display_id(); + let bounds = display_id.bounds(); + + if window_center_x >= bounds.origin.x + && window_center_x < bounds.origin.x + bounds.size.width + && window_center_y >= bounds.origin.y + && window_center_y < bounds.origin.y + bounds.size.height + { + // Found the display containing the window's center + if let Some(mode) = display_id.display_mode() { + return (mode.pixel_width() / mode.width()) as f64; + } + } + } + } + + // Fallback: if we can't determine the display or get scale factor, use 1.0 + 1.0 + } Target::Display(display) => { let mode = display.raw_handle.display_mode().unwrap(); (mode.pixel_width() / mode.width()) as f64 @@ -102,13 +130,21 @@ pub fn get_scale_factor(target: &Target) -> f64 { pub fn get_target_dimensions(target: &Target) -> (u64, u64) { match target { - Target::Window(window) => unsafe { + Target::Window(window) => { let cg_win_id = window.raw_handle; - let ns_app: id = NSApp(); - let ns_window: id = msg_send![ns_app, windowWithWindowNumber: cg_win_id as NSUInteger]; - let frame: NSRect = msg_send![ns_window, frame]; - (frame.size.width as u64, frame.size.height as u64) - }, + + // Use ScreenCaptureKit directly to get window dimensions + let content = block_on(sc::ShareableContent::current()).unwrap(); + for sc_window in content.windows().iter() { + if sc_window.id() == cg_win_id { + let frame = sc_window.frame(); + return (frame.size.width as u64, frame.size.height as u64); + } + } + + // Fallback to default dimensions if window not found + (800, 600) + } Target::Display(display) => { let mode = display.raw_handle.display_mode().unwrap(); (mode.width(), mode.height()) From 1a8e6695428a07ffeb5323ecc074e63c05a5069f Mon Sep 17 00:00:00 2001 From: Keath Milligan Date: Mon, 25 Aug 2025 00:00:50 -0500 Subject: [PATCH 2/2] Return scaled dimensions, robustness --- src/targets/mac/mod.rs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/targets/mac/mod.rs b/src/targets/mac/mod.rs index a09ca68..3c8e700 100644 --- a/src/targets/mac/mod.rs +++ b/src/targets/mac/mod.rs @@ -88,7 +88,10 @@ pub fn get_scale_factor(target: &Target) -> f64 { match target { Target::Window(window) => { // Get the window's frame to determine which display it's on - let content = block_on(sc::ShareableContent::current()).unwrap(); + let content = match block_on(sc::ShareableContent::current()) { + Ok(c) => c, + Err(_) => return 1.0, // fallback on SC failures to avoid panic + }; // Find the window in ScreenCaptureKit if let Some(sc_window) = content @@ -112,7 +115,7 @@ pub fn get_scale_factor(target: &Target) -> f64 { { // Found the display containing the window's center if let Some(mode) = display_id.display_mode() { - return (mode.pixel_width() / mode.width()) as f64; + return (mode.pixel_width() as f64) / mode.width() as f64; } } } @@ -134,14 +137,17 @@ pub fn get_target_dimensions(target: &Target) -> (u64, u64) { let cg_win_id = window.raw_handle; // Use ScreenCaptureKit directly to get window dimensions - let content = block_on(sc::ShareableContent::current()).unwrap(); - for sc_window in content.windows().iter() { - if sc_window.id() == cg_win_id { - let frame = sc_window.frame(); - return (frame.size.width as u64, frame.size.height as u64); - } + let content = match block_on(sc::ShareableContent::current()) { + Ok(c) => c, + Err(_) => return (800, 600), // conservative fallback on SC failures + }; + if let Some(sc_window) = content.windows().iter().find(|w| w.id() == cg_win_id) { + let frame = sc_window.frame(); // points + let scale = get_scale_factor(target); // uses SC as well; safe to reuse + let w_px = (frame.size.width * scale).round() as u64; + let h_px = (frame.size.height * scale).round() as u64; + return (w_px, h_px); } - // Fallback to default dimensions if window not found (800, 600) }