diff --git a/Cargo.lock b/Cargo.lock index f048c88d2..c33d195d7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -876,6 +876,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" version = "1.19.0" @@ -1398,6 +1404,7 @@ dependencies = [ "log", "miniz_oxide 0.8.9", "naga", + "open", "png", "pollster", "rustix 1.1.5", @@ -1877,6 +1884,25 @@ dependencies = [ "windows-sys 0.61.2", ] +[[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 = "itertools" version = "0.14.0" @@ -2691,6 +2717,17 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "open" +version = "5.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d8c8b8e725ad26404d6896eb2f064294a0a7b4f1d9120210d85544684c4ca95" +dependencies = [ + "dunce", + "is-wsl", + "libc", +] + [[package]] name = "orbclient" version = "0.3.55" diff --git a/crates/horizon-client/Cargo.toml b/crates/horizon-client/Cargo.toml index 74c593bc6..66ca987dc 100644 --- a/crates/horizon-client/Cargo.toml +++ b/crates/horizon-client/Cargo.toml @@ -70,6 +70,8 @@ unicode-bidi = "0.3.18" rustix = { version = "1", default-features = false, features = ["std", "time"] } [target.'cfg(windows)'.dependencies] +# Use the registered URI handler without routing links through Explorer/cmd. +open = { version = "5.4.5", features = ["shellexecute-on-windows"] } # DirectX 12, where Vulkan has no adapter or device, or by choice (`graphicsApi`, graphics.rs). # Shaders compile with FXC (d3dcompiler_47.dll, part of Windows), or DXC when dxcompiler.dll is # on the PATH. diff --git a/crates/horizon-client/src/game/packs.rs b/crates/horizon-client/src/game/packs.rs index 013b94de2..2096e8c0e 100644 --- a/crates/horizon-client/src/game/packs.rs +++ b/crates/horizon-client/src/game/packs.rs @@ -45,6 +45,14 @@ pub fn open_folder(dir: &Path) { } /// `Util.getPlatform().openUri`: the system browser on the link. pub fn open_uri(uri: &str) { + // URLs need Windows' registered protocol handler, not Explorer's path + // handling. ShellExecute also preserves the URL as one Unicode value, + // without interpolating its query string into a command interpreter. + #[cfg(windows)] + if let Err(error) = open::that_detached(uri) { + log::warn!("Horizon: could not open URI {uri}: {error}"); + } + #[cfg(not(windows))] open_folder(Path::new(uri)); } /// The resource root to load from, given the vanilla root, the selection and