@@ -232,28 +232,56 @@ fn get_monitor_with_cursor(app_handle: &AppHandle) -> Option<tauri::Monitor> {
232232
233233fn calculate_overlay_position ( app_handle : & AppHandle ) -> Option < ( f64 , f64 ) > {
234234 if let Some ( monitor) = get_monitor_with_cursor ( app_handle) {
235- let work_area = monitor. work_area ( ) ;
236235 let scale = monitor. scale_factor ( ) ;
237- let work_area_width = work_area. size . width as f64 / scale;
238- let work_area_height = work_area. size . height as f64 / scale;
239- let work_area_x = work_area. position . x as f64 / scale;
240- let work_area_y = work_area. position . y as f64 / scale;
236+ let monitor_x = monitor. position ( ) . x as f64 / scale;
237+ let monitor_y = monitor. position ( ) . y as f64 / scale;
238+ let monitor_width = monitor. size ( ) . width as f64 / scale;
239+ let monitor_height = monitor. size ( ) . height as f64 / scale;
240+
241+ let work_area = monitor. work_area ( ) ;
242+ let wa_x = work_area. position . x as f64 / scale;
243+ let wa_y = work_area. position . y as f64 / scale;
244+ let wa_w = work_area. size . width as f64 / scale;
245+ let wa_h = work_area. size . height as f64 / scale;
246+
247+ // Validate work_area: on macOS, work_area() can return bogus values
248+ // for external monitors. Detect this by checking if work_area extends
249+ // beyond the monitor bounds.
250+ let wa_bottom = wa_y + wa_h;
251+ let monitor_bottom = monitor_y + monitor_height;
252+ let work_area_valid =
253+ wa_y >= monitor_y && wa_bottom <= monitor_bottom + 1.0 && wa_w <= monitor_width + 1.0 ;
254+
255+ let ( area_x, area_y, area_w, area_h) = if work_area_valid {
256+ ( wa_x, wa_y, wa_w, wa_h)
257+ } else {
258+ log:: debug!(
259+ "work_area invalid for monitor (wa_bottom={:.0} > monitor_bottom={:.0}), using monitor bounds with safe offset" ,
260+ wa_bottom, monitor_bottom
261+ ) ;
262+ // Use monitor bounds with a safe top offset for the macOS menu bar (~25px)
263+ let menu_bar_offset = 25.0 ;
264+ (
265+ monitor_x,
266+ monitor_y + menu_bar_offset,
267+ monitor_width,
268+ monitor_height - menu_bar_offset,
269+ )
270+ } ;
241271
242272 let settings = settings:: get_settings ( app_handle) ;
243273
244- let x = work_area_x + ( work_area_width - OVERLAY_WIDTH ) / 2.0 ;
274+ let x = area_x + ( area_w - OVERLAY_WIDTH ) / 2.0 ;
245275 let y = match settings. overlay_position {
246- OverlayPosition :: Top => work_area_y + OVERLAY_TOP_OFFSET ,
276+ OverlayPosition :: Top => area_y + OVERLAY_TOP_OFFSET ,
247277 OverlayPosition :: Bottom | OverlayPosition :: None => {
248- work_area_y + work_area_height - OVERLAY_HEIGHT - OVERLAY_BOTTOM_OFFSET
278+ area_y + area_h - OVERLAY_HEIGHT - OVERLAY_BOTTOM_OFFSET
249279 }
250280 } ;
251281
252282 log:: debug!(
253- "Overlay position: ({:.0}, {:.0}) on monitor (scale={}, work_area=({:.0},{:.0},{:.0},{:.0}))" ,
254- x, y,
255- scale,
256- work_area_x, work_area_y, work_area_width, work_area_height
283+ "Overlay position: ({:.0}, {:.0}) on monitor (scale={}, area=({:.0},{:.0},{:.0},{:.0}), wa_valid={})" ,
284+ x, y, scale, area_x, area_y, area_w, area_h, work_area_valid
257285 ) ;
258286
259287 return Some ( ( x, y) ) ;
@@ -356,7 +384,6 @@ pub fn create_recording_overlay(app_handle: &AppHandle) {
356384}
357385
358386fn show_overlay_state ( app_handle : & AppHandle , state : & str ) {
359- // Check if overlay should be shown based on position setting
360387 let settings = settings:: get_settings ( app_handle) ;
361388 if settings. overlay_position == OverlayPosition :: None {
362389 return ;
@@ -367,7 +394,6 @@ fn show_overlay_state(app_handle: &AppHandle, state: &str) {
367394 if let Some ( overlay_window) = app_handle. get_webview_window ( "recording_overlay" ) {
368395 let _ = overlay_window. show ( ) ;
369396
370- // On Windows, aggressively re-assert "topmost" in the native Z-order after showing
371397 #[ cfg( target_os = "windows" ) ]
372398 force_overlay_topmost ( & overlay_window) ;
373399
0 commit comments