From cf83ecccbb8f1fe28ea533b103efdb3091dd8578 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 16 Feb 2023 10:36:46 -0800 Subject: [PATCH 1/4] Added workspace restart command --- Cargo.lock | 1 + crates/cli/Cargo.toml | 1 + crates/cli/src/main.rs | 13 ++++++++- crates/workspace/src/workspace.rs | 1 + crates/zed/src/main.rs | 8 ++++++ crates/zed/src/zed.rs | 44 ++++++++++++++++++++++++------- 6 files changed, 58 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75c084d3ef..abf9a12f0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1097,6 +1097,7 @@ dependencies = [ "ipc-channel", "plist", "serde", + "sysinfo", ] [[package]] diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index f2bab22ea7..98c5ba60ab 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -18,6 +18,7 @@ clap = { version = "3.1", features = ["derive"] } dirs = "3.0" ipc-channel = "0.16" serde = { version = "1.0", features = ["derive", "rc"] } +sysinfo = "0.27" [target.'cfg(target_os = "macos")'.dependencies] core-foundation = "0.9" diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index a31e59587f..8ef1b1fb2b 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -14,8 +14,10 @@ use std::{ fs::{self, OpenOptions}, io, path::{Path, PathBuf}, - ptr, + ptr, thread, + time::Duration, }; +use sysinfo::{Pid, System, SystemExt}; #[derive(Parser)] #[clap(name = "zed", global_setting(clap::AppSettings::NoAutoVersion))] @@ -32,6 +34,8 @@ struct Args { /// Custom Zed.app path #[clap(short, long)] bundle_path: Option, + #[clap(short, long)] + restart_from: Option, } #[derive(Debug, Deserialize)] @@ -60,6 +64,13 @@ fn main() -> Result<()> { return Ok(()); } + if let Some(parent_pid) = args.restart_from { + let mut system = System::new(); + while system.refresh_process(parent_pid) { + thread::sleep(Duration::from_millis(100)); + } + } + for path in args.paths.iter() { if !path.exists() { touch(path.as_path())?; 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..5679bce53a 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -567,6 +567,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..d6e8a1a4be 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -23,7 +23,8 @@ use gpui::{ }, impl_actions, platform::{WindowBounds, WindowOptions}, - AssetSource, AsyncAppContext, Platform, PromptLevel, TitlebarOptions, ViewContext, WindowKind, + AssetSource, AsyncAppContext, Platform, PromptLevel, Task, TitlebarOptions, ViewContext, + WindowKind, }; use language::Rope; use lazy_static::lazy_static; @@ -34,11 +35,11 @@ use search::{BufferSearchBar, ProjectSearchBar}; use serde::Deserialize; use serde_json::to_string_pretty; use settings::{keymap_file_json_schema, settings_file_json_schema, Settings}; -use std::{borrow::Cow, env, path::Path, str, sync::Arc}; +use std::{borrow::Cow, env, path::Path, process::Command, 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 { @@ -129,7 +130,10 @@ pub fn init(app_state: &Arc, cx: &mut gpui::MutableAppContext) { } }, ); - cx.add_global_action(quit); + cx.add_global_action(|_: &Quit, cx| { + quit(cx).detach_and_log_err(cx); + }); + 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,7 +407,29 @@ pub fn build_window_options( } } -fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) { +fn restart(_: &Restart, cx: &mut gpui::MutableAppContext) { + let cli_process = dbg!(cx.platform().path_for_auxiliary_executable("cli")) + .log_err() + .and_then(|path| { + Command::new(path) + .args(["--restart-from", &format!("{}", dbg!(std::process::id()))]) + .spawn() + .log_err() + }); + + cx.spawn(|mut cx| async move { + let did_quit = dbg!(cx.update(quit).await?); + if !did_quit { + if let Some(mut cli_process) = cli_process { + cli_process.kill().log_err(); + } + } + Ok::<(), anyhow::Error>(()) + }) + .detach_and_log_err(cx); +} + +fn quit(cx: &mut gpui::MutableAppContext) -> Task> { let mut workspaces = cx .window_ids() .filter_map(|window_id| cx.root_view::(window_id)) @@ -426,7 +452,7 @@ fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) { .next() .await; if answer != Some(0) { - return Ok(()); + return Ok(false); } } @@ -438,13 +464,13 @@ fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) { }) .await? { - return Ok(()); + return Ok(false); } } + dbg!("about to quit"); cx.platform().quit(); - anyhow::Ok(()) + anyhow::Ok(true) }) - .detach_and_log_err(cx); } fn about(_: &mut Workspace, _: &About, cx: &mut gpui::ViewContext) { From 43f61ab413a1dfccf5a9c4645c96aad7f8f9b291 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 16 Feb 2023 13:35:32 -0800 Subject: [PATCH 2/4] Added action to autoupdate --- crates/activity_indicator/src/activity_indicator.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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(), From 4ea7a24b93a535cb0d26e509a9b26363aced181b Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 16 Feb 2023 14:41:03 -0800 Subject: [PATCH 3/4] Made the 'update zed to collaborate' button clickable --- Cargo.lock | 1 + crates/collab_ui/Cargo.toml | 1 + crates/collab_ui/src/collab_titlebar_item.rs | 25 +++++++++++++------- crates/zed/src/zed.rs | 9 +++---- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index abf9a12f0e..e45ed5c433 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1253,6 +1253,7 @@ name = "collab_ui" version = "0.1.0" dependencies = [ "anyhow", + "auto_update", "call", "client", "clock", 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/zed/src/zed.rs b/crates/zed/src/zed.rs index d6e8a1a4be..7be2818b61 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -408,17 +408,19 @@ pub fn build_window_options( } fn restart(_: &Restart, cx: &mut gpui::MutableAppContext) { - let cli_process = dbg!(cx.platform().path_for_auxiliary_executable("cli")) + let cli_process = cx + .platform() + .path_for_auxiliary_executable("cli") .log_err() .and_then(|path| { Command::new(path) - .args(["--restart-from", &format!("{}", dbg!(std::process::id()))]) + .args(["--restart-from", &format!("{}", std::process::id())]) .spawn() .log_err() }); cx.spawn(|mut cx| async move { - let did_quit = dbg!(cx.update(quit).await?); + let did_quit = cx.update(quit).await?; if !did_quit { if let Some(mut cli_process) = cli_process { cli_process.kill().log_err(); @@ -467,7 +469,6 @@ fn quit(cx: &mut gpui::MutableAppContext) -> Task> { return Ok(false); } } - dbg!("about to quit"); cx.platform().quit(); anyhow::Ok(true) }) From 6e33f33da1aee44535a6d9c4438592b8d0a8ba65 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 16 Feb 2023 16:35:34 -0800 Subject: [PATCH 4/4] Switch to open based restarting --- Cargo.lock | 1 - crates/cli/Cargo.toml | 1 - crates/cli/src/main.rs | 13 +------- crates/gpui/src/platform.rs | 1 + crates/gpui/src/platform/mac/platform.rs | 28 +++++++++++++++++ crates/gpui/src/platform/test.rs | 2 ++ crates/zed/src/main.rs | 4 ++- crates/zed/src/zed.rs | 40 ++++++------------------ 8 files changed, 44 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e45ed5c433..fb94530b6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1097,7 +1097,6 @@ dependencies = [ "ipc-channel", "plist", "serde", - "sysinfo", ] [[package]] diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 98c5ba60ab..f2bab22ea7 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -18,7 +18,6 @@ clap = { version = "3.1", features = ["derive"] } dirs = "3.0" ipc-channel = "0.16" serde = { version = "1.0", features = ["derive", "rc"] } -sysinfo = "0.27" [target.'cfg(target_os = "macos")'.dependencies] core-foundation = "0.9" diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 8ef1b1fb2b..a31e59587f 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -14,10 +14,8 @@ use std::{ fs::{self, OpenOptions}, io, path::{Path, PathBuf}, - ptr, thread, - time::Duration, + ptr, }; -use sysinfo::{Pid, System, SystemExt}; #[derive(Parser)] #[clap(name = "zed", global_setting(clap::AppSettings::NoAutoVersion))] @@ -34,8 +32,6 @@ struct Args { /// Custom Zed.app path #[clap(short, long)] bundle_path: Option, - #[clap(short, long)] - restart_from: Option, } #[derive(Debug, Deserialize)] @@ -64,13 +60,6 @@ fn main() -> Result<()> { return Ok(()); } - if let Some(parent_pid) = args.restart_from { - let mut system = System::new(); - while system.refresh_process(parent_pid) { - thread::sleep(Duration::from_millis(100)); - } - } - for path in args.paths.iter() { if !path.exists() { touch(path.as_path())?; 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/zed/src/main.rs b/crates/zed/src/main.rs index 5679bce53a..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, }; diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 7be2818b61..16b5413fda 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -23,8 +23,7 @@ use gpui::{ }, impl_actions, platform::{WindowBounds, WindowOptions}, - AssetSource, AsyncAppContext, Platform, PromptLevel, Task, TitlebarOptions, ViewContext, - WindowKind, + AssetSource, AsyncAppContext, Platform, PromptLevel, TitlebarOptions, ViewContext, WindowKind, }; use language::Rope; use lazy_static::lazy_static; @@ -35,7 +34,7 @@ use search::{BufferSearchBar, ProjectSearchBar}; use serde::Deserialize; use serde_json::to_string_pretty; use settings::{keymap_file_json_schema, settings_file_json_schema, Settings}; -use std::{borrow::Cow, env, path::Path, process::Command, str, sync::Arc}; +use std::{borrow::Cow, env, path::Path, str, sync::Arc}; use util::{channel::ReleaseChannel, paths, ResultExt, StaffMode}; use uuid::Uuid; pub use workspace; @@ -130,9 +129,7 @@ pub fn init(app_state: &Arc, cx: &mut gpui::MutableAppContext) { } }, ); - cx.add_global_action(|_: &Quit, cx| { - quit(cx).detach_and_log_err(cx); - }); + 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| { @@ -408,30 +405,10 @@ pub fn build_window_options( } fn restart(_: &Restart, cx: &mut gpui::MutableAppContext) { - let cli_process = cx - .platform() - .path_for_auxiliary_executable("cli") - .log_err() - .and_then(|path| { - Command::new(path) - .args(["--restart-from", &format!("{}", std::process::id())]) - .spawn() - .log_err() - }); - - cx.spawn(|mut cx| async move { - let did_quit = cx.update(quit).await?; - if !did_quit { - if let Some(mut cli_process) = cli_process { - cli_process.kill().log_err(); - } - } - Ok::<(), anyhow::Error>(()) - }) - .detach_and_log_err(cx); + cx.platform().restart(); } -fn quit(cx: &mut gpui::MutableAppContext) -> Task> { +fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) { let mut workspaces = cx .window_ids() .filter_map(|window_id| cx.root_view::(window_id)) @@ -454,7 +431,7 @@ fn quit(cx: &mut gpui::MutableAppContext) -> Task> { .next() .await; if answer != Some(0) { - return Ok(false); + return Ok(()); } } @@ -466,12 +443,13 @@ fn quit(cx: &mut gpui::MutableAppContext) -> Task> { }) .await? { - return Ok(false); + return Ok(()); } } cx.platform().quit(); - anyhow::Ok(true) + anyhow::Ok(()) }) + .detach_and_log_err(cx); } fn about(_: &mut Workspace, _: &About, cx: &mut gpui::ViewContext) {