From 2b62b0b73c6dc8b5ba3ce11679aa5e83754665d4 Mon Sep 17 00:00:00 2001 From: Iuliia Ivashko Date: Fri, 30 Jan 2026 01:07:39 +0200 Subject: [PATCH] fix: macOS traffic lights and header padding --- packages/desktop/src-tauri/src/main.rs | 53 +++++++++++++++++-- packages/ui/src/components/layout/Header.tsx | 2 +- .../components/multirun/MultiRunLauncher.tsx | 2 +- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/packages/desktop/src-tauri/src/main.rs b/packages/desktop/src-tauri/src/main.rs index 341c6600..d1dc59b8 100644 --- a/packages/desktop/src-tauri/src/main.rs +++ b/packages/desktop/src-tauri/src/main.rs @@ -324,6 +324,15 @@ fn get_macos_major_version() -> isize { version.majorVersion } +#[cfg(target_os = "macos")] +fn get_traffic_light_y(macos_version: isize) -> f64 { + if macos_version <= 15 { + 4.0 + } else { + 16.0 + } +} + #[cfg(target_os = "macos")] fn adjust_traffic_lights_position( window: &tauri::WebviewWindow, @@ -351,6 +360,41 @@ fn adjust_traffic_lights_position( } } +#[cfg(target_os = "macos")] +fn adjust_traffic_lights_centered( + window: &tauri::WebviewWindow, + fallback_x: f64, + y: f64, +) { + use objc2::msg_send; + use objc2::runtime::AnyObject; + use objc2_foundation::{NSPoint, NSRect}; + + if let Ok(ns_window) = window.ns_window() { + unsafe { + let ns_window: *mut AnyObject = ns_window.cast(); + let close_button: *mut AnyObject = msg_send![ns_window, standardWindowButton: 0usize]; + + if !close_button.is_null() { + let superview: *mut AnyObject = msg_send![close_button, superview]; + if !superview.is_null() { + let frame: NSRect = msg_send![superview, frame]; + let parent: *mut AnyObject = msg_send![superview, superview]; + if !parent.is_null() { + let parent_frame: NSRect = msg_send![parent, frame]; + let new_x = (parent_frame.size.width - frame.size.width) / 2.0; + let new_frame = NSRect::new(NSPoint::new(new_x, y), frame.size); + let _: () = msg_send![superview, setFrame: new_frame]; + return; + } + } + } + } + } + + adjust_traffic_lights_position(window, fallback_x, y); +} + #[cfg(target_os = "macos")] fn optimize_webview_layer(window: &tauri::WebviewWindow) { use objc2::msg_send; @@ -715,9 +759,10 @@ fn main() { let macos_version = get_macos_major_version(); info!("[macos] Detected macOS version: {}", macos_version); - if macos_version < 26 { + if macos_version <= 15 { NEEDS_TRAFFIC_LIGHT_FIX.store(true, Ordering::SeqCst); - adjust_traffic_lights_position(&window, 17.0, 16.0); + let traffic_light_y = get_traffic_light_y(macos_version); + adjust_traffic_lights_centered(&window, 17.0, traffic_light_y); } // Apply layer optimizations for smoother scrolling @@ -1087,7 +1132,9 @@ fn main() { #[cfg(target_os = "macos")] if NEEDS_TRAFFIC_LIGHT_FIX.load(Ordering::SeqCst) { if let Some(webview) = window.app_handle().get_webview_window("main") { - adjust_traffic_lights_position(&webview, 17.0, 16.0); + let macos_version = get_macos_major_version(); + let traffic_light_y = get_traffic_light_y(macos_version); + adjust_traffic_lights_centered(&webview, 17.0, traffic_light_y); } } } diff --git a/packages/ui/src/components/layout/Header.tsx b/packages/ui/src/components/layout/Header.tsx index 86191364..0b9ece79 100644 --- a/packages/ui/src/components/layout/Header.tsx +++ b/packages/ui/src/components/layout/Header.tsx @@ -284,7 +284,7 @@ export const Header: React.FC = () => { const desktopPaddingClass = React.useMemo(() => { if (isDesktopApp && isMacPlatform) { // Always reserve space for Mac traffic lights since header is always on top - return 'pl-[5.75rem]'; + return 'pl-[5.125rem]'; } return 'pl-3'; }, [isDesktopApp, isMacPlatform]); diff --git a/packages/ui/src/components/multirun/MultiRunLauncher.tsx b/packages/ui/src/components/multirun/MultiRunLauncher.tsx index 78ed41f6..699f3809 100644 --- a/packages/ui/src/components/multirun/MultiRunLauncher.tsx +++ b/packages/ui/src/components/multirun/MultiRunLauncher.tsx @@ -116,7 +116,7 @@ export const MultiRunLauncher: React.FC = ({ const desktopHeaderPaddingClass = React.useMemo(() => { if (isDesktopApp && isMacPlatform) { // Match main app header: reserve space for Mac traffic lights. - return 'pl-[5.75rem]'; + return 'pl-[5.125rem]'; } return 'pl-3'; }, [isDesktopApp, isMacPlatform]);