From 0ee900e8fbdb9643552e0504cb6c3e9daa2df5bf Mon Sep 17 00:00:00 2001 From: Chung Wei Leong <15154097+chungweileong94@users.noreply.github.com> Date: Sat, 31 May 2025 01:13:50 +0800 Subject: [PATCH] Support macOS Sequoia titlebar double-click action (#30468) Closes #16527 Release Notes: - Added MacOS titlebar double-click action --- Unfortunately, Apple doesn't seem to make the "Fill" API public or documented anywhere. Co-authored-by: Mikayla Maki --- crates/gpui/src/platform.rs | 1 + crates/gpui/src/platform/mac/window.rs | 44 ++++++++++++++++++++++++++ crates/gpui/src/window.rs | 6 ++++ crates/title_bar/src/title_bar.rs | 9 +++++- 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index f84a590db0..9687879006 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -445,6 +445,7 @@ pub(crate) trait PlatformWindow: HasWindowHandle + HasDisplayHandle { // macOS specific methods fn set_edited(&mut self, _edited: bool) {} fn show_character_palette(&self) {} + fn titlebar_double_click(&self) {} #[cfg(target_os = "windows")] fn get_raw_handle(&self) -> windows::HWND; diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index dd5ec4eb31..651ee1e4ad 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -19,6 +19,7 @@ use cocoa::{ foundation::{ NSArray, NSAutoreleasePool, NSDictionary, NSFastEnumeration, NSInteger, NSNotFound, NSOperatingSystemVersion, NSPoint, NSProcessInfo, NSRect, NSSize, NSString, NSUInteger, + NSUserDefaults, }, }; use core_graphics::display::{CGDirectDisplayID, CGPoint, CGRect}; @@ -1177,6 +1178,49 @@ impl PlatformWindow for MacWindow { }) .detach() } + + fn titlebar_double_click(&self) { + let this = self.0.lock(); + let window = this.native_window; + this.executor + .spawn(async move { + unsafe { + let defaults: id = NSUserDefaults::standardUserDefaults(); + let domain = NSString::alloc(nil).init_str("NSGlobalDomain"); + let key = NSString::alloc(nil).init_str("AppleActionOnDoubleClick"); + + let dict: id = msg_send![defaults, persistentDomainForName: domain]; + let action: id = if !dict.is_null() { + msg_send![dict, objectForKey: key] + } else { + nil + }; + + let action_str = if !action.is_null() { + CStr::from_ptr(NSString::UTF8String(action)).to_string_lossy() + } else { + "".into() + }; + + match action_str.as_ref() { + "Minimize" => { + window.miniaturize_(nil); + } + "Maximize" => { + window.zoom_(nil); + } + "Fill" => { + // There is no documented API for "Fill" action, so we'll just zoom the window + window.zoom_(nil); + } + _ => { + window.zoom_(nil); + } + } + } + }) + .detach(); + } } impl rwh::HasWindowHandle for MacWindow { diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 8636268a7a..5ebdf93f19 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -4011,6 +4011,12 @@ impl Window { self.platform_window.gpu_specs() } + /// Perform titlebar double-click action. + /// This is MacOS specific. + pub fn titlebar_double_click(&self) { + self.platform_window.titlebar_double_click(); + } + /// Toggles the inspector mode on this window. #[cfg(any(feature = "inspector", debug_assertions))] pub fn toggle_inspector(&mut self, cx: &mut App) { diff --git a/crates/title_bar/src/title_bar.rs b/crates/title_bar/src/title_bar.rs index d2c9131a14..b17bb872f9 100644 --- a/crates/title_bar/src/title_bar.rs +++ b/crates/title_bar/src/title_bar.rs @@ -179,7 +179,14 @@ impl Render for TitleBar { .justify_between() .w_full() // Note: On Windows the title bar behavior is handled by the platform implementation. - .when(self.platform_style != PlatformStyle::Windows, |this| { + .when(self.platform_style == PlatformStyle::Mac, |this| { + this.on_click(|event, window, _| { + if event.up.click_count == 2 { + window.titlebar_double_click(); + } + }) + }) + .when(self.platform_style == PlatformStyle::Linux, |this| { this.on_click(|event, window, _| { if event.up.click_count == 2 { window.zoom_window();