diff --git a/src/windows.rs b/src/windows.rs index 0558222..a47f45e 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -7,14 +7,42 @@ use std::os::windows::process::CommandExt; const CREATE_NO_WINDOW: u32 = 0x08000000; +/// Detects if the current process is running under Wine by checking environment +/// variables that Wine injects into guest processes. +fn is_running_under_wine() -> bool { + std::env::var_os("WINEPREFIX").is_some() + || std::env::var_os("WINELOADER").is_some() + || std::env::var_os("WINEDEBUG").is_some() +} + +/// Constructs a Command to invoke Wine's winebrowser utility, which forwards +/// file/URL open requests to the host OS's default handler. +fn winebrowser_command>(path: T) -> Command { + let mut cmd = Command::new("winebrowser"); + cmd.arg(path.as_ref()); + // Match Windows behavior: suppress console window flash + cmd.creation_flags(CREATE_NO_WINDOW); + cmd +} + pub fn commands>(path: T) -> Vec { + let mut cmds = Vec::new(); + let path = path.as_ref(); + + // When under Wine, try winebrowser first for seamless host integration. + if is_running_under_wine() { + cmds.push(winebrowser_command(path)); + } + let mut cmd = Command::new("cmd"); cmd.arg("/c") .arg("start") .raw_arg("\"\"") .raw_arg(wrap_in_quotes(path)) .creation_flags(CREATE_NO_WINDOW); - vec![cmd] + cmds.push(cmd); + + cmds } pub fn with_command>(path: T, app: impl Into) -> Command {