Merge pull request #2184 from zed-industries/relaunch

Mikayla Maki created

Restart

Change summary

Cargo.lock                                          |  1 
crates/activity_indicator/src/activity_indicator.rs |  6 ++
crates/collab_ui/Cargo.toml                         |  1 
crates/collab_ui/src/collab_titlebar_item.rs        | 25 +++++++++----
crates/gpui/src/platform.rs                         |  1 
crates/gpui/src/platform/mac/platform.rs            | 28 +++++++++++++++
crates/gpui/src/platform/test.rs                    |  2 +
crates/workspace/src/workspace.rs                   |  1 
crates/zed/src/main.rs                              | 12 +++++
crates/zed/src/zed.rs                               |  7 +++
10 files changed, 73 insertions(+), 11 deletions(-)

Detailed changes

Cargo.lock πŸ”—

@@ -1252,6 +1252,7 @@ name = "collab_ui"
 version = "0.1.0"
 dependencies = [
  "anyhow",
+ "auto_update",
  "call",
  "client",
  "clock",

crates/activity_indicator/src/activity_indicator.rs πŸ”—

@@ -252,7 +252,11 @@ impl ActivityIndicator {
                     "Installing Zed update…".to_string(),
                     None,
                 ),
-                AutoUpdateStatus::Updated => (None, "Restart to update Zed".to_string(), None),
+                AutoUpdateStatus::Updated => (
+                    None,
+                    "Click to restart and update Zed".to_string(),
+                    Some(Box::new(workspace::Restart)),
+                ),
                 AutoUpdateStatus::Errored => (
                     Some(WARNING_ICON),
                     "Auto update failed".to_string(),

crates/collab_ui/Cargo.toml πŸ”—

@@ -22,6 +22,7 @@ test-support = [
 ]
 
 [dependencies]
+auto_update = { path = "../auto_update" }
 call = { path = "../call" }
 client = { path = "../client" }
 clock = { path = "../clock" }

crates/collab_ui/src/collab_titlebar_item.rs πŸ”—

@@ -504,7 +504,9 @@ impl CollabTitlebarItem {
         workspace: &ViewHandle<Workspace>,
         cx: &mut RenderContext<Self>,
     ) -> Option<ElementBox> {
-        let theme = &cx.global::<Settings>().theme;
+        enum ConnectionStatusButton {}
+
+        let theme = &cx.global::<Settings>().theme.clone();
         match &*workspace.read(cx).client().status().borrow() {
             client::Status::ConnectionError
             | client::Status::ConnectionLost
@@ -527,13 +529,20 @@ impl CollabTitlebarItem {
                 .boxed(),
             ),
             client::Status::UpgradeRequired => Some(
-                Label::new(
-                    "Please update Zed to collaborate".to_string(),
-                    theme.workspace.titlebar.outdated_warning.text.clone(),
-                )
-                .contained()
-                .with_style(theme.workspace.titlebar.outdated_warning.container)
-                .aligned()
+                MouseEventHandler::<ConnectionStatusButton>::new(0, cx, |_, _| {
+                    Label::new(
+                        "Please update Zed to collaborate".to_string(),
+                        theme.workspace.titlebar.outdated_warning.text.clone(),
+                    )
+                    .contained()
+                    .with_style(theme.workspace.titlebar.outdated_warning.container)
+                    .aligned()
+                    .boxed()
+                })
+                .with_cursor_style(CursorStyle::PointingHand)
+                .on_click(MouseButton::Left, |_, cx| {
+                    cx.dispatch_action(auto_update::Check);
+                })
                 .boxed(),
             ),
             _ => None,

crates/gpui/src/platform.rs πŸ”—

@@ -81,6 +81,7 @@ pub trait Platform: Send + Sync {
     fn app_version(&self) -> Result<AppVersion>;
     fn os_name(&self) -> &'static str;
     fn os_version(&self) -> Result<AppVersion>;
+    fn restart(&self);
 }
 
 pub(crate) trait ForegroundPlatform {

crates/gpui/src/platform/mac/platform.rs πŸ”—

@@ -45,6 +45,7 @@ use std::{
     ffi::{c_void, CStr, OsStr},
     os::{raw::c_char, unix::ffi::OsStrExt},
     path::{Path, PathBuf},
+    process::Command,
     ptr,
     rc::Rc,
     slice, str,
@@ -803,6 +804,33 @@ impl platform::Platform for MacPlatform {
             })
         }
     }
+
+    fn restart(&self) {
+        #[cfg(debug_assertions)]
+        let path = std::env::current_exe();
+
+        #[cfg(not(debug_assertions))]
+        let path = unsafe {
+            let bundle: id = NSBundle::mainBundle();
+            if bundle.is_null() {
+                std::env::current_exe()
+            } else {
+                let path: id = msg_send![bundle, bundlePath];
+                let path: *mut c_char = msg_send![path, UTF8String];
+
+                Ok(PathBuf::from(OsStr::from_bytes(
+                    CStr::from_ptr(path).to_bytes(),
+                )))
+            }
+        };
+
+        let command = path.and_then(|path| Command::new("/usr/bin/open").arg(path).spawn());
+
+        match command {
+            Err(err) => log::error!("Unable to restart application {}", err),
+            Ok(_) => self.quit(),
+        }
+    }
 }
 
 unsafe fn path_from_objc(path: id) -> PathBuf {

crates/zed/src/main.rs πŸ”—

@@ -38,7 +38,9 @@ use terminal_view::{get_working_directory, TerminalView};
 use fs::RealFs;
 use settings::watched_json::{watch_keymap_file, watch_settings_file, WatchedJsonFile};
 use theme::ThemeRegistry;
-use util::{channel::RELEASE_CHANNEL, paths, ResultExt, StaffMode, TryFutureExt};
+#[cfg(debug_assertions)]
+use util::StaffMode;
+use util::{channel::RELEASE_CHANNEL, paths, ResultExt, TryFutureExt};
 use workspace::{
     self, item::ItemHandle, notifications::NotifyResultExt, AppState, NewFile, OpenPaths, Workspace,
 };
@@ -567,6 +569,14 @@ async fn handle_cli_connection(
     if let Some(request) = requests.next().await {
         match request {
             CliRequest::Open { paths, wait } => {
+                let paths = if paths.is_empty() {
+                    workspace::last_opened_workspace_paths()
+                        .await
+                        .map(|location| location.paths().to_vec())
+                        .unwrap_or(paths)
+                } else {
+                    paths
+                };
                 let (workspace, items) = cx
                     .update(|cx| workspace::open_paths(&paths, &app_state, cx))
                     .await;

crates/zed/src/zed.rs πŸ”—

@@ -38,7 +38,7 @@ use std::{borrow::Cow, env, path::Path, str, sync::Arc};
 use util::{channel::ReleaseChannel, paths, ResultExt, StaffMode};
 use uuid::Uuid;
 pub use workspace;
-use workspace::{sidebar::SidebarSide, AppState, Workspace};
+use workspace::{sidebar::SidebarSide, AppState, Restart, Workspace};
 
 #[derive(Deserialize, Clone, PartialEq)]
 pub struct OpenBrowser {
@@ -130,6 +130,7 @@ pub fn init(app_state: &Arc<AppState>, cx: &mut gpui::MutableAppContext) {
         },
     );
     cx.add_global_action(quit);
+    cx.add_global_action(restart);
     cx.add_global_action(move |action: &OpenBrowser, cx| cx.platform().open_url(&action.url));
     cx.add_global_action(move |_: &IncreaseBufferFontSize, cx| {
         cx.update_global::<Settings, _, _>(|settings, cx| {
@@ -403,6 +404,10 @@ pub fn build_window_options(
     }
 }
 
+fn restart(_: &Restart, cx: &mut gpui::MutableAppContext) {
+    cx.platform().restart();
+}
+
 fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) {
     let mut workspaces = cx
         .window_ids()