From b5f762ab25f1e9ccf5438010181dcc5644ac2ead Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 29 Mar 2023 17:24:44 -0700 Subject: [PATCH] Open a new window when activating Zed from the dock w/ no windows open --- crates/gpui/src/app.rs | 17 +++++++++-- crates/gpui/src/platform.rs | 4 +++ crates/gpui/src/platform/mac/platform.rs | 37 ++++++++++++++++++------ crates/gpui/src/platform/test.rs | 5 +--- crates/zed/src/main.rs | 3 +- 5 files changed, 49 insertions(+), 17 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 0c8256fefb..755568431d 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -254,6 +254,19 @@ impl App { self } + /// Handle the application being re-activated when no windows are open. + pub fn on_reopen(&mut self, mut callback: F) -> &mut Self + where + F: 'static + FnMut(&mut MutableAppContext), + { + let cx = self.0.clone(); + self.0 + .borrow_mut() + .foreground_platform + .on_reopen(Box::new(move || callback(&mut *cx.borrow_mut()))); + self + } + pub fn on_event(&mut self, mut callback: F) -> &mut Self where F: 'static + FnMut(Event, &mut MutableAppContext) -> bool, @@ -276,9 +289,7 @@ impl App { self.0 .borrow_mut() .foreground_platform - .on_open_urls(Box::new(move |paths| { - callback(paths, &mut *cx.borrow_mut()) - })); + .on_open_urls(Box::new(move |urls| callback(urls, &mut *cx.borrow_mut()))); self } diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 538b46ee77..4c0c319745 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -90,6 +90,10 @@ pub(crate) trait ForegroundPlatform { fn on_become_active(&self, callback: Box); fn on_resign_active(&self, callback: Box); fn on_quit(&self, callback: Box); + + /// Handle the application being re-activated with no windows open. + fn on_reopen(&self, callback: Box); + fn on_event(&self, callback: Box bool>); fn on_open_urls(&self, callback: Box)>); fn run(&self, on_finish_launching: Box); diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index ab4fd873c6..7e901e8a5e 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -82,6 +82,10 @@ unsafe fn build_classes() { sel!(applicationDidFinishLaunching:), did_finish_launching as extern "C" fn(&mut Object, Sel, id), ); + decl.add_method( + sel!(applicationShouldHandleReopen:hasVisibleWindows:), + should_handle_reopen as extern "C" fn(&mut Object, Sel, id, bool), + ); decl.add_method( sel!(applicationDidBecomeActive:), did_become_active as extern "C" fn(&mut Object, Sel, id), @@ -144,6 +148,7 @@ pub struct MacForegroundPlatform(RefCell); pub struct MacForegroundPlatformState { become_active: Option>, resign_active: Option>, + reopen: Option>, quit: Option>, event: Option bool>>, menu_command: Option>, @@ -158,15 +163,16 @@ pub struct MacForegroundPlatformState { impl MacForegroundPlatform { pub fn new(foreground: Rc) -> Self { Self(RefCell::new(MacForegroundPlatformState { - become_active: Default::default(), - resign_active: Default::default(), - quit: Default::default(), - event: Default::default(), - menu_command: Default::default(), - validate_menu_command: Default::default(), - will_open_menu: Default::default(), - open_urls: Default::default(), - finish_launching: Default::default(), + become_active: None, + resign_active: None, + reopen: None, + quit: None, + event: None, + menu_command: None, + validate_menu_command: None, + will_open_menu: None, + open_urls: None, + finish_launching: None, menu_actions: Default::default(), foreground, })) @@ -332,6 +338,10 @@ impl platform::ForegroundPlatform for MacForegroundPlatform { self.0.borrow_mut().quit = Some(callback); } + fn on_reopen(&self, callback: Box) { + self.0.borrow_mut().reopen = Some(callback); + } + fn on_event(&self, callback: Box bool>) { self.0.borrow_mut().event = Some(callback); } @@ -943,6 +953,15 @@ extern "C" fn did_finish_launching(this: &mut Object, _: Sel, _: id) { } } +extern "C" fn should_handle_reopen(this: &mut Object, _: Sel, _: id, has_open_windows: bool) { + if !has_open_windows { + let platform = unsafe { get_foreground_platform(this) }; + if let Some(callback) = platform.0.borrow_mut().reopen.as_mut() { + callback(); + } + } +} + extern "C" fn did_become_active(this: &mut Object, _: Sel, _: id) { let platform = unsafe { get_foreground_platform(this) }; if let Some(callback) = platform.0.borrow_mut().become_active.as_mut() { diff --git a/crates/gpui/src/platform/test.rs b/crates/gpui/src/platform/test.rs index a3532dd96e..b6b2fe5217 100644 --- a/crates/gpui/src/platform/test.rs +++ b/crates/gpui/src/platform/test.rs @@ -61,13 +61,10 @@ impl ForegroundPlatform { impl super::ForegroundPlatform for ForegroundPlatform { fn on_become_active(&self, _: Box) {} - fn on_resign_active(&self, _: Box) {} - fn on_quit(&self, _: Box) {} - + fn on_reopen(&self, _: Box) {} fn on_event(&self, _: Box bool>) {} - fn on_open_urls(&self, _: Box)>) {} fn run(&self, _on_finish_launching: Box) { diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index fb6c6227c3..99628da8d9 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -105,7 +105,8 @@ fn main() { .map_err(|_| anyhow!("no listener for open urls requests")) .log_err(); } - }); + }) + .on_reopen(move |cx| cx.dispatch_global_action(NewFile)); app.run(move |cx| { cx.set_global(*RELEASE_CHANNEL);