add own open_url crate

The upstream open crate keeps making stuff async/blocking/not-working on
windows, so this is a step towards removing this dependency.

refs: https://github.com/wez/wezterm/issues/3288
This commit is contained in:
Wez Furlong 2023-03-19 12:44:12 -07:00
parent e70ec47134
commit f5ba73a1a2
No known key found for this signature in database
GPG Key ID: 7A7F66A31EC9B387
12 changed files with 91 additions and 31 deletions

14
Cargo.lock generated
View File

@ -4755,9 +4755,9 @@ dependencies = [
"config",
"log",
"luahelper",
"open",
"smol",
"wezterm-dynamic",
"wezterm-open-url",
"winapi",
]
@ -5987,7 +5987,6 @@ dependencies = [
"mux",
"mux-lua",
"once_cell",
"open",
"ordered-float",
"parking_lot 0.12.1",
"portable-pty",
@ -6024,6 +6023,7 @@ dependencies = [
"wezterm-font",
"wezterm-gui-subcommands",
"wezterm-mux-server-impl",
"wezterm-open-url",
"wezterm-ssh",
"wezterm-term",
"wezterm-toast-notification",
@ -6102,6 +6102,14 @@ dependencies = [
"winapi",
]
[[package]]
name = "wezterm-open-url"
version = "0.1.0"
dependencies = [
"open",
"winapi",
]
[[package]]
name = "wezterm-ssh"
version = "0.4.0"
@ -6175,8 +6183,8 @@ dependencies = [
"futures-util",
"log",
"objc",
"open",
"serde",
"wezterm-open-url",
"windows 0.33.0",
"xml-rs",
"zbus",

View File

@ -9,6 +9,7 @@ members = [
"wezterm-dynamic",
"wezterm-gui",
"wezterm-mux-server",
"wezterm-open-url",
"wezterm-ssh"
]
resolver = "2"

View File

@ -13,7 +13,7 @@ log = "0.4"
luahelper = { path = "../../luahelper" }
smol = "1.2"
bstr = "0.2"
open = "4.0"
wezterm-open-url = { path = "../../wezterm-open-url" }
[target."cfg(windows)".dependencies]
winapi = { version = "0.3", features = ["winuser"]}

View File

@ -18,13 +18,9 @@ pub fn register(lua: &Lua) -> anyhow::Result<()> {
fn open_with<'lua>(_: &'lua Lua, (url, app): (String, Option<String>)) -> mlua::Result<()> {
if let Some(app) = app {
open::with_in_background(url, app);
wezterm_open_url::open_with(&url, &app);
} else {
std::thread::spawn(move || {
if let Err(err) = open::that(&url) {
log::error!("Error opening {}: {:#}", url, err);
}
});
wezterm_open_url::open_url(&url);
}
Ok(())
}

View File

@ -67,7 +67,6 @@ mlua = {version="0.8.3", features=["send"]}
mux = { path = "../mux" }
mux-lua = { path = "../lua-api-crates/mux" }
once_cell = "1.8"
open = "4.0"
ordered-float = "3.0"
parking_lot = "0.12"
portable-pty = { path = "../pty", features = ["serde_support"]}
@ -102,6 +101,7 @@ wezterm-dynamic = { path = "../wezterm-dynamic" }
wezterm-font = { path = "../wezterm-font" }
wezterm-gui-subcommands = { path = "../wezterm-gui-subcommands" }
wezterm-mux-server-impl = { path = "../wezterm-mux-server-impl" }
wezterm-open-url = { path = "../wezterm-open-url" }
wezterm-ssh = { path = "../wezterm-ssh" }
wezterm-term = { path = "../term", features=["use_serde"] }
wezterm-toast-notification = { path = "../wezterm-toast-notification" }

View File

@ -2810,12 +2810,7 @@ impl TermWindow {
)]);
}
OpenUri(link) => {
let link = link.clone();
std::thread::spawn(move || {
if let Err(err) = open::that(&link) {
log::error!("Error opening {}: {:#}", link, err);
}
});
wezterm_open_url::open_url(link);
}
ActivateCommandPalette => {
let modal = crate::termwindow::palette::CommandPalette::new(self);
@ -2832,7 +2827,7 @@ impl TermWindow {
// triggering our WndProc recursively.
// We get that assurance for free as part of the async dispatch that we
// perform below; here we allow the user to define an `open-uri` event
// handler that can bypass the normal `open::that` functionality.
// handler that can bypass the normal `open_url` functionality.
if let Some(link) = self.current_highlight.as_ref().cloned() {
let window = GuiWin::new(self);
let pane = MuxPane(pane.pane_id());
@ -2856,12 +2851,8 @@ impl TermWindow {
None => true,
};
if default_click {
std::thread::spawn(move || {
log::info!("clicking {}", link);
if let Err(err) = open::that(&link) {
log::error!("Error opening {}: {:#}", link, err);
}
});
log::info!("clicking {}", link);
wezterm_open_url::open_url(&link);
}
Ok(())
}

View File

@ -0,0 +1,10 @@
[package]
name = "wezterm-open-url"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
open = "4.0"
winapi = {version="0.3", features=["shellapi"]}

View File

@ -0,0 +1,57 @@
#[cfg(not(windows))]
pub fn open_url(url: &str) {
let url = url.to_string();
std::thread::spawn(move || {
let _ = open::that(&url);
});
}
#[cfg(not(windows))]
pub fn open_with(url: &str, app: &str) {
open::with_in_background(url, app);
}
#[cfg(windows)]
fn shell_execute(url: String, with: Option<String>) {
use std::os::windows::ffi::OsStrExt;
use winapi::um::shellapi::ShellExecuteW;
/// Convert a rust string to a windows wide string
fn wide_string(s: &str) -> Vec<u16> {
std::ffi::OsStr::new(s)
.encode_wide()
.chain(std::iter::once(0))
.collect()
}
std::thread::spawn(move || {
let operation = wide_string("open");
let url = wide_string(&url);
let with = with.map(|s| wide_string(&s));
let (app, path) = match with {
Some(app) => (app.as_ptr(), url.as_ptr()),
None => (url.as_ptr(), std::ptr::null()),
};
unsafe {
ShellExecuteW(
std::ptr::null_mut(),
operation.as_ptr(),
app,
path,
std::ptr::null(),
winapi::um::winuser::SW_SHOW,
);
}
});
}
#[cfg(windows)]
pub fn open_url(url: &str) {
shell_execute(url.to_string(), None);
}
#[cfg(windows)]
pub fn open_with(url: &str, app: &str) {
shell_execute(url.to_string(), Some(app.to_string()));
}

View File

@ -8,7 +8,7 @@ build = "build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
open = "4.0"
wezterm-open-url = { path = "../wezterm-open-url" }
log = "0.4"
[target.'cfg(all(not(windows), not(target_os="macos")))'.dependencies]

View File

@ -126,10 +126,7 @@ async fn show_notif_impl(notif: ToastNotification) -> Result<(), Box<dyn std::er
let args = signal.args()?;
if args.nid == notification {
if let Some(url) = notif.url.as_ref() {
let url = url.clone();
std::thread::spawn(move || {
let _ = open::that(url);
});
wezterm_open_url::open_url(url);
abort_closed.abort();
break;
}

View File

@ -65,7 +65,7 @@ impl NotifDelegate {
if !url.is_null() {
let url = std::slice::from_raw_parts(url.UTF8String() as *const u8, url.len());
let url = String::from_utf8_lossy(url);
let _ = open::that(&*url);
wezterm_open_url::open_url(&*url);
}
let () = msg_send![center, removeDeliveredNotification: notif];
}

View File

@ -57,7 +57,7 @@ fn show_notif_impl(toast: TN) -> Result<(), Box<dyn std::error::Error>> {
if args == "show" {
if let Some(url) = toast.url.as_ref() {
let _ = open::that(url);
wezterm_open_url::open_url(url);
}
}