Remove release channel from Zed URLs (#8863)
Also adds a new command `cli: Register Zed Scheme` that will cause URLs to be opened in the current zed version, and we call this implicitly if you install the CLI Also add some status reporting to install cli Fixes: #8857 Release Notes: - Added success/error reporting to `cli: Install Cli` ([#8857](https://github.com/zed-industries/zed/issues/8857)). - Removed `zed-{preview,nightly,dev}:` url schemes (used by channel links) - Added `cli: Register Zed Scheme` to control which zed handles the `zed://` scheme (defaults to the most recently installed, or the version that you last used `cli: Install Cli` with)
This commit is contained in:
parent
2201b9b116
commit
f53823c840
21 changed files with 178 additions and 113 deletions
|
@ -566,6 +566,14 @@ impl AppContext {
|
|||
self.platform.open_url(url);
|
||||
}
|
||||
|
||||
/// register_url_scheme requests that the given scheme (e.g. `zed` for `zed://` urls)
|
||||
/// is opened by the current app.
|
||||
/// On some platforms (e.g. macOS) you may be able to register URL schemes as part of app
|
||||
/// distribution, but this method exists to let you register schemes at runtime.
|
||||
pub fn register_url_scheme(&self, scheme: &str) -> Task<Result<()>> {
|
||||
self.platform.register_url_scheme(scheme)
|
||||
}
|
||||
|
||||
/// Returns the full pathname of the current app bundle.
|
||||
/// If the app is not being run from a bundle, returns an error.
|
||||
pub fn app_path(&self) -> Result<PathBuf> {
|
||||
|
|
|
@ -101,6 +101,8 @@ pub(crate) trait Platform: 'static {
|
|||
|
||||
fn open_url(&self, url: &str);
|
||||
fn on_open_urls(&self, callback: Box<dyn FnMut(Vec<String>)>);
|
||||
fn register_url_scheme(&self, url: &str) -> Task<Result<()>>;
|
||||
|
||||
fn prompt_for_paths(
|
||||
&self,
|
||||
options: PathPromptOptions,
|
||||
|
|
|
@ -441,6 +441,10 @@ impl Platform for LinuxPlatform {
|
|||
fn window_appearance(&self) -> crate::WindowAppearance {
|
||||
crate::WindowAppearance::Light
|
||||
}
|
||||
|
||||
fn register_url_scheme(&self, _: &str) -> Task<anyhow::Result<()>> {
|
||||
Task::ready(Err(anyhow!("register_url_scheme unimplemented")))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -525,6 +525,49 @@ impl Platform for MacPlatform {
|
|||
}
|
||||
}
|
||||
|
||||
fn register_url_scheme(&self, scheme: &str) -> Task<anyhow::Result<()>> {
|
||||
// API only available post Monterey
|
||||
// https://developer.apple.com/documentation/appkit/nsworkspace/3753004-setdefaultapplicationaturl
|
||||
let (done_tx, done_rx) = oneshot::channel();
|
||||
if self.os_version().ok() < Some(SemanticVersion::new(12, 0, 0)) {
|
||||
return Task::ready(Err(anyhow!(
|
||||
"macOS 12.0 or later is required to register URL schemes"
|
||||
)));
|
||||
}
|
||||
|
||||
let bundle_id = unsafe {
|
||||
let bundle: id = msg_send![class!(NSBundle), mainBundle];
|
||||
let bundle_id: id = msg_send![bundle, bundleIdentifier];
|
||||
if bundle_id == nil {
|
||||
return Task::ready(Err(anyhow!("Can only register URL scheme in bundled apps")));
|
||||
}
|
||||
bundle_id
|
||||
};
|
||||
|
||||
unsafe {
|
||||
let workspace: id = msg_send![class!(NSWorkspace), sharedWorkspace];
|
||||
let scheme: id = ns_string(scheme);
|
||||
let app: id = msg_send![workspace, URLForApplicationWithBundleIdentifier: bundle_id];
|
||||
let done_tx = Cell::new(Some(done_tx));
|
||||
let block = ConcreteBlock::new(move |error: id| {
|
||||
let result = if error == nil {
|
||||
Ok(())
|
||||
} else {
|
||||
let msg: id = msg_send![error, localizedDescription];
|
||||
Err(anyhow!("Failed to register: {:?}", msg))
|
||||
};
|
||||
|
||||
if let Some(done_tx) = done_tx.take() {
|
||||
let _ = done_tx.send(result);
|
||||
}
|
||||
});
|
||||
let _: () = msg_send![workspace, setDefaultApplicationAtURL: app toOpenURLsWithScheme: scheme completionHandler: block];
|
||||
}
|
||||
|
||||
self.background_executor()
|
||||
.spawn(async { crate::Flatten::flatten(done_rx.await.map_err(|e| anyhow!(e))) })
|
||||
}
|
||||
|
||||
fn on_open_urls(&self, callback: Box<dyn FnMut(Vec<String>)>) {
|
||||
self.0.lock().open_urls = Some(callback);
|
||||
}
|
||||
|
|
|
@ -298,4 +298,8 @@ impl Platform for TestPlatform {
|
|||
fn double_click_interval(&self) -> std::time::Duration {
|
||||
Duration::from_millis(500)
|
||||
}
|
||||
|
||||
fn register_url_scheme(&self, _: &str) -> Task<anyhow::Result<()>> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -314,4 +314,8 @@ impl Platform for WindowsPlatform {
|
|||
fn delete_credentials(&self, url: &str) -> Task<Result<()>> {
|
||||
Task::Ready(Some(Err(anyhow!("not implemented yet."))))
|
||||
}
|
||||
|
||||
fn register_url_scheme(&self, _: &str) -> Task<anyhow::Result<()>> {
|
||||
Task::ready(Err(anyhow!("register_url_scheme unimplemented")))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue