linux: re-add open fallback (#14359)

Conrad Irwin created

Release Notes:

- linux: Fixed opening urls/directories on systems where the xdg desktop
portal doesn't handle those requests.

Change summary

Cargo.lock                                 | 31 +++++++++++++++++++++
crates/gpui/Cargo.toml                     |  1 
crates/gpui/src/platform/linux/platform.rs | 35 +++++++++++++++++++----
3 files changed, 61 insertions(+), 6 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -4902,6 +4902,7 @@ dependencies = [
  "num_cpus",
  "objc",
  "oo7",
+ "open",
  "parking",
  "parking_lot",
  "pathfinder_geometry",
@@ -5713,6 +5714,25 @@ version = "2.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
 
+[[package]]
+name = "is-docker"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "is-wsl"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5"
+dependencies = [
+ "is-docker",
+ "once_cell",
+]
+
 [[package]]
 name = "isahc"
 version = "1.7.2"
@@ -7195,6 +7215,17 @@ version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
 
+[[package]]
+name = "open"
+version = "5.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61a877bf6abd716642a53ef1b89fb498923a4afca5c754f9050b4d081c05c4b3"
+dependencies = [
+ "is-wsl",
+ "libc",
+ "pathdiff",
+]
+
 [[package]]
 name = "open_ai"
 version = "0.1.0"

crates/gpui/Cargo.toml 🔗

@@ -124,6 +124,7 @@ wayland-protocols = { version = "0.31.2", features = [
 ] }
 wayland-protocols-plasma = { version = "0.2.0", features = ["client"] }
 oo7 = "0.3.0"
+open = "5.2.0"
 filedescriptor = "0.8.2"
 x11rb = { version = "0.13.0", features = [
     "allow-unsafe-code",

crates/gpui/src/platform/linux/platform.rs 🔗

@@ -525,11 +525,26 @@ pub(super) fn open_uri_internal(
     if let Some(uri) = url::Url::parse(uri).log_err() {
         executor
             .spawn(async move {
-                OpenUriRequest::default()
-                    .activation_token(activation_token.map(ActivationToken::from))
+                match OpenUriRequest::default()
+                    .activation_token(activation_token.clone().map(ActivationToken::from))
                     .send_uri(&uri)
                     .await
-                    .log_err();
+                {
+                    Ok(_) => return,
+                    Err(e) => log::error!("Failed to open with dbus: {}", e),
+                }
+
+                for mut command in open::commands(uri.to_string()) {
+                    if let Some(token) = activation_token.as_ref() {
+                        command.env("XDG_ACTIVATION_TOKEN", token);
+                    }
+                    match command.spawn() {
+                        Ok(_) => return,
+                        Err(e) => {
+                            log::error!("Failed to open with {:?}: {}", command.get_program(), e)
+                        }
+                    }
+                }
             })
             .detach();
     }
@@ -542,12 +557,20 @@ pub(super) fn reveal_path_internal(
 ) {
     executor
         .spawn(async move {
-            if let Some(dir) = File::open(path).log_err() {
-                OpenDirectoryRequest::default()
+            if let Some(dir) = File::open(path.clone()).log_err() {
+                match OpenDirectoryRequest::default()
                     .activation_token(activation_token.map(ActivationToken::from))
                     .send(&dir.as_fd())
                     .await
-                    .log_err();
+                {
+                    Ok(_) => return,
+                    Err(e) => log::error!("Failed to open with dbus: {}", e),
+                }
+                if path.is_dir() {
+                    open::that_detached(path).log_err();
+                } else {
+                    open::that_detached(path.parent().unwrap_or(Path::new(""))).log_err();
+                }
             }
         })
         .detach();