diff --git a/src/main.rs b/src/main.rs index 812a776..b10a80a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -310,7 +310,12 @@ impl TerminalWindow { } fn sync_title(&self) { - self.window.set_title(self.active().title()); + let title = self.active().title(); + self.window.set_title(title); + #[cfg(target_os = "macos")] + if let Some(ns_view) = ns_view_ptr(&self.window) { + platform::set_tab_title(ns_view, title); + } } fn accept_ghost(&mut self) { diff --git a/src/platform.rs b/src/platform.rs index 5bb1286..e6999cf 100644 --- a/src/platform.rs +++ b/src/platform.rs @@ -214,3 +214,25 @@ pub fn select_prev_tab(ns_view: *mut std::ffi::c_void) { } } } + +/// Update the native macOS tab label for this window. +/// `NSWindowTab.title` is separate from `NSWindow.title` and doesn't +/// automatically follow it after the window is added to a tab group. +#[cfg(target_os = "macos")] +pub fn set_tab_title(ns_view: *mut std::ffi::c_void, title: &str) { + use objc2::{msg_send, runtime::AnyObject}; + use std::os::raw::c_char; + unsafe { + let view: *mut AnyObject = ns_view as *mut AnyObject; + let win: *mut AnyObject = msg_send![view, window]; + if win.is_null() { return; } + let tab: *mut AnyObject = msg_send![win, tab]; + if tab.is_null() { return; } + let ns_str: *mut AnyObject = msg_send![ + objc2::class!(NSString), + stringWithUTF8String: title.as_ptr() as *const c_char + ]; + if ns_str.is_null() { return; } + let _: () = msg_send![tab, setTitle: ns_str]; + } +}