Detailed changes
@@ -281,11 +281,14 @@ impl ActivityIndicator {
message: "Installing Zed updateβ¦".to_string(),
on_click: None,
},
- AutoUpdateStatus::Updated => Content {
+ AutoUpdateStatus::Updated { binary_path } => Content {
icon: None,
message: "Click to restart and update Zed".to_string(),
- on_click: Some(Arc::new(|_, cx| {
- workspace::restart(&Default::default(), cx)
+ on_click: Some(Arc::new({
+ let restart = workspace::Restart {
+ binary_path: Some(binary_path.clone()),
+ };
+ move |_, cx| workspace::restart(&restart, cx)
})),
},
AutoUpdateStatus::Errored => Content {
@@ -56,16 +56,22 @@ struct UpdateRequestBody {
telemetry: bool,
}
-#[derive(Clone, Copy, PartialEq, Eq)]
+#[derive(Clone, PartialEq, Eq)]
pub enum AutoUpdateStatus {
Idle,
Checking,
Downloading,
Installing,
- Updated,
+ Updated { binary_path: PathBuf },
Errored,
}
+impl AutoUpdateStatus {
+ pub fn is_updated(&self) -> bool {
+ matches!(self, Self::Updated { .. })
+ }
+}
+
pub struct AutoUpdater {
status: AutoUpdateStatus,
current_version: SemanticVersion,
@@ -306,7 +312,7 @@ impl AutoUpdater {
}
pub fn poll(&mut self, cx: &mut ModelContext<Self>) {
- if self.pending_poll.is_some() || self.status == AutoUpdateStatus::Updated {
+ if self.pending_poll.is_some() || self.status.is_updated() {
return;
}
@@ -328,7 +334,7 @@ impl AutoUpdater {
}
pub fn status(&self) -> AutoUpdateStatus {
- self.status
+ self.status.clone()
}
pub fn dismiss_error(&mut self, cx: &mut ModelContext<Self>) {
@@ -404,6 +410,11 @@ impl AutoUpdater {
cx.notify();
})?;
+ // We store the path of our current binary, before we install, since installation might
+ // delete it. Once deleted, it's hard to get the path to our binary on Linux.
+ // So we cache it here, which allows us to then restart later on.
+ let binary_path = cx.update(|cx| cx.app_path())??;
+
match OS {
"macos" => install_release_macos(&temp_dir, downloaded_asset, &cx).await,
"linux" => install_release_linux(&temp_dir, downloaded_asset, &cx).await,
@@ -413,7 +424,7 @@ impl AutoUpdater {
this.update(&mut cx, |this, cx| {
this.set_should_show_update_notification(true, cx)
.detach_and_log_err(cx);
- this.status = AutoUpdateStatus::Updated;
+ this.status = AutoUpdateStatus::Updated { binary_path };
cx.notify();
})?;
@@ -677,7 +677,7 @@ impl CollabTitlebarItem {
client::Status::UpgradeRequired => {
let auto_updater = auto_update::AutoUpdater::get(cx);
let label = match auto_updater.map(|auto_update| auto_update.read(cx).status()) {
- Some(AutoUpdateStatus::Updated) => "Please restart Zed to Collaborate",
+ Some(AutoUpdateStatus::Updated { .. }) => "Please restart Zed to Collaborate",
Some(AutoUpdateStatus::Installing)
| Some(AutoUpdateStatus::Downloading)
| Some(AutoUpdateStatus::Checking) => "Updating...",
@@ -691,7 +691,7 @@ impl CollabTitlebarItem {
.label_size(LabelSize::Small)
.on_click(|_, cx| {
if let Some(auto_updater) = auto_update::AutoUpdater::get(cx) {
- if auto_updater.read(cx).status() == AutoUpdateStatus::Updated {
+ if auto_updater.read(cx).status().is_updated() {
workspace::restart(&Default::default(), cx);
return;
}
@@ -642,8 +642,8 @@ impl AppContext {
}
/// Restart the application.
- pub fn restart(&self) {
- self.platform.restart()
+ pub fn restart(&self, binary_path: Option<PathBuf>) {
+ self.platform.restart(binary_path)
}
/// Returns the local timezone at the platform level.
@@ -98,7 +98,7 @@ pub(crate) trait Platform: 'static {
fn run(&self, on_finish_launching: Box<dyn 'static + FnOnce()>);
fn quit(&self);
- fn restart(&self);
+ fn restart(&self, binary_path: Option<PathBuf>);
fn activate(&self, ignoring_other_apps: bool);
fn hide(&self);
fn hide_other_apps(&self);
@@ -136,17 +136,21 @@ impl<P: LinuxClient + 'static> Platform for P {
self.with_common(|common| common.signal.stop());
}
- fn restart(&self) {
+ fn restart(&self, binary_path: Option<PathBuf>) {
use std::os::unix::process::CommandExt as _;
// get the process id of the current process
let app_pid = std::process::id().to_string();
// get the path to the executable
- let app_path = match self.app_path() {
- Ok(path) => path,
- Err(err) => {
- log::error!("Failed to get app path: {:?}", err);
- return;
+ let app_path = if let Some(path) = binary_path {
+ path
+ } else {
+ match self.app_path() {
+ Ok(path) => path,
+ Err(err) => {
+ log::error!("Failed to get app path: {:?}", err);
+ return;
+ }
}
};
@@ -396,7 +396,7 @@ impl Platform for MacPlatform {
}
}
- fn restart(&self) {
+ fn restart(&self, _binary_path: Option<PathBuf>) {
use std::os::unix::process::CommandExt as _;
let app_pid = std::process::id().to_string();
@@ -140,7 +140,7 @@ impl Platform for TestPlatform {
fn quit(&self) {}
- fn restart(&self) {
+ fn restart(&self, _: Option<PathBuf>) {
unimplemented!()
}
@@ -268,7 +268,7 @@ impl Platform for WindowsPlatform {
.detach();
}
- fn restart(&self) {
+ fn restart(&self, _: Option<PathBuf>) {
let pid = std::process::id();
let Some(app_path) = self.app_path().log_err() else {
return;
@@ -130,7 +130,6 @@ actions!(
NewCenterTerminal,
NewSearch,
Feedback,
- Restart,
Welcome,
ToggleZoom,
ToggleLeftDock,
@@ -185,6 +184,11 @@ pub struct CloseInactiveTabsAndPanes {
#[derive(Clone, Deserialize, PartialEq)]
pub struct SendKeystrokes(pub String);
+#[derive(Clone, Deserialize, PartialEq, Default)]
+pub struct Restart {
+ pub binary_path: Option<PathBuf>,
+}
+
impl_actions!(
workspace,
[
@@ -194,6 +198,7 @@ impl_actions!(
CloseInactiveTabsAndPanes,
NewFileInDirection,
OpenTerminal,
+ Restart,
Save,
SaveAll,
SwapPaneInDirection,
@@ -5020,7 +5025,7 @@ pub fn join_in_room_project(
})
}
-pub fn restart(_: &Restart, cx: &mut AppContext) {
+pub fn restart(restart: &Restart, cx: &mut AppContext) {
let should_confirm = WorkspaceSettings::get_global(cx).confirm_quit;
let mut workspace_windows = cx
.windows()
@@ -5046,6 +5051,7 @@ pub fn restart(_: &Restart, cx: &mut AppContext) {
.ok();
}
+ let binary_path = restart.binary_path.clone();
cx.spawn(|mut cx| async move {
if let Some(prompt) = prompt {
let answer = prompt.await?;
@@ -5065,7 +5071,7 @@ pub fn restart(_: &Restart, cx: &mut AppContext) {
}
}
- cx.update(|cx| cx.restart())
+ cx.update(|cx| cx.restart(binary_path))
})
.detach_and_log_err(cx);
}