diff --git a/Cargo.lock b/Cargo.lock index 757868813e..e8410b25f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1252,6 +1252,7 @@ name = "collab_ui" version = "0.1.0" dependencies = [ "anyhow", + "auto_update", "call", "client", "clock", diff --git a/crates/activity_indicator/src/activity_indicator.rs b/crates/activity_indicator/src/activity_indicator.rs index 8b9eb4b040..f3a6f7328a 100644 --- a/crates/activity_indicator/src/activity_indicator.rs +++ b/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(), diff --git a/crates/collab_ui/Cargo.toml b/crates/collab_ui/Cargo.toml index ac13e361fd..2dc4cc769a 100644 --- a/crates/collab_ui/Cargo.toml +++ b/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" } diff --git a/crates/collab_ui/src/collab_titlebar_item.rs b/crates/collab_ui/src/collab_titlebar_item.rs index 9f2c0fbee9..184a432ea3 100644 --- a/crates/collab_ui/src/collab_titlebar_item.rs +++ b/crates/collab_ui/src/collab_titlebar_item.rs @@ -504,7 +504,9 @@ impl CollabTitlebarItem { workspace: &ViewHandle, cx: &mut RenderContext, ) -> Option { - let theme = &cx.global::().theme; + enum ConnectionStatusButton {} + + let theme = &cx.global::().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::::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, diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 4753450110..1bf19e983e 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -81,6 +81,7 @@ pub trait Platform: Send + Sync { fn app_version(&self) -> Result; fn os_name(&self) -> &'static str; fn os_version(&self) -> Result; + fn restart(&self); } pub(crate) trait ForegroundPlatform { diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index ccbae5a832..3db7c6eedc 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/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 { diff --git a/crates/gpui/src/platform/test.rs b/crates/gpui/src/platform/test.rs index cf0e31c2b8..e81daa8788 100644 --- a/crates/gpui/src/platform/test.rs +++ b/crates/gpui/src/platform/test.rs @@ -226,6 +226,8 @@ impl super::Platform for Platform { patch: 0, }) } + + fn restart(&self) {} } #[derive(Debug)] diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 8d81ae7f2e..bf4fb11522 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -101,6 +101,7 @@ actions!( NewTerminal, NewSearch, Feedback, + Restart ] ); diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 77fd516b86..a775b31bc4 100644 --- a/crates/zed/src/main.rs +++ b/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; diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index bf9afe136e..16b5413fda 100644 --- a/crates/zed/src/zed.rs +++ b/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, 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, 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()