diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index eb4b9650a6..2604848e3b 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -542,12 +542,23 @@ impl TestAppContext { !prompts.is_empty() } - #[cfg(any(test, feature = "test-support"))] + pub fn current_window_title(&self, window_id: usize) -> Option { + let mut state = self.cx.borrow_mut(); + let (_, window) = state + .presenters_and_platform_windows + .get_mut(&window_id) + .unwrap(); + let test_window = window + .as_any_mut() + .downcast_mut::() + .unwrap(); + test_window.title.clone() + } + pub fn leak_detector(&self) -> Arc> { self.cx.borrow().leak_detector() } - #[cfg(any(test, feature = "test-support"))] pub fn assert_dropped(&self, handle: impl WeakHandle) { self.cx .borrow() @@ -3265,6 +3276,13 @@ impl<'a, T: View> ViewContext<'a, T> { self.app.focus(self.window_id, None); } + pub fn set_window_title(&mut self, title: &str) { + let window_id = self.window_id(); + if let Some((_, window)) = self.presenters_and_platform_windows.get_mut(&window_id) { + window.set_title(title); + } + } + pub fn add_model(&mut self, build_model: F) -> ModelHandle where S: Entity, diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index c4b68c0741..16a6481a43 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -96,6 +96,7 @@ pub trait Window: WindowContext { fn on_close(&mut self, callback: Box); fn prompt(&self, level: PromptLevel, msg: &str, answers: &[&str]) -> oneshot::Receiver; fn activate(&self); + fn set_title(&mut self, title: &str); } pub trait WindowContext { diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index 26cde46c04..7ace58f428 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -202,6 +202,11 @@ impl MacForegroundPlatform { menu_bar_item.setSubmenu_(menu); menu_bar.addItem_(menu_bar_item); + + if menu_name == "Window" { + let app: id = msg_send![APP_CLASS, sharedApplication]; + app.setWindowsMenu_(menu); + } } menu_bar diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 518cefcd60..5d6848cd7b 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -386,8 +386,15 @@ impl platform::Window for Window { } fn activate(&self) { + unsafe { msg_send![self.0.borrow().native_window, makeKeyAndOrderFront: nil] } + } + + fn set_title(&mut self, title: &str) { unsafe { - let _: () = msg_send![self.0.borrow().native_window, makeKeyAndOrderFront: nil]; + let app = NSApplication::sharedApplication(nil); + let window = self.0.borrow().native_window; + let title = ns_string(title); + msg_send![app, changeWindowsItem:window title:title filename:false] } } } diff --git a/crates/gpui/src/platform/test.rs b/crates/gpui/src/platform/test.rs index a3d5cc5406..e22db89e3b 100644 --- a/crates/gpui/src/platform/test.rs +++ b/crates/gpui/src/platform/test.rs @@ -37,6 +37,7 @@ pub struct Window { event_handlers: Vec>, resize_handlers: Vec>, close_handlers: Vec>, + pub(crate) title: Option, pub(crate) pending_prompts: RefCell>>, } @@ -189,9 +190,14 @@ impl Window { close_handlers: Vec::new(), scale_factor: 1.0, current_scene: None, + title: None, pending_prompts: Default::default(), } } + + pub fn title(&self) -> Option { + self.title.clone() + } } impl super::Dispatcher for Dispatcher { @@ -248,6 +254,10 @@ impl super::Window for Window { } fn activate(&self) {} + + fn set_title(&mut self, title: &str) { + self.title = Some(title.to_string()) + } } pub fn platform() -> Platform {