Support macOS Sequoia titlebar double-click action (#30468)

Chung Wei Leong and Mikayla Maki created

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 <mikayla@zed.dev>

Change summary

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(-)

Detailed changes

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;

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 {

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) {

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();