fix(win32): Sidecar spawning a window (#14197)

This commit is contained in:
Luke Parker
2026-02-19 08:18:15 +10:00
committed by GitHub
parent 87c16374aa
commit 7033b4d0a8
3 changed files with 22 additions and 6 deletions

View File

@@ -3136,6 +3136,7 @@ dependencies = [
"tracing-subscriber", "tracing-subscriber",
"uuid", "uuid",
"webkit2gtk", "webkit2gtk",
"windows 0.62.2",
] ]
[[package]] [[package]]

View File

@@ -54,6 +54,9 @@ chrono = "0.4"
tokio-stream = { version = "0.1.18", features = ["sync"] } tokio-stream = { version = "0.1.18", features = ["sync"] }
process-wrap = { version = "9.0.3", features = ["tokio1"] } process-wrap = { version = "9.0.3", features = ["tokio1"] }
[target.'cfg(windows)'.dependencies]
windows = { version = "0.62", features = ["Win32_System_Threading"] }
[target.'cfg(target_os = "linux")'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
gtk = "0.18.2" gtk = "0.18.2"
webkit2gtk = "=2.0.2" webkit2gtk = "=2.0.2"

View File

@@ -3,7 +3,7 @@ use process_wrap::tokio::CommandWrap;
#[cfg(unix)] #[cfg(unix)]
use process_wrap::tokio::ProcessGroup; use process_wrap::tokio::ProcessGroup;
#[cfg(windows)] #[cfg(windows)]
use process_wrap::tokio::{JobObject, KillOnDrop}; use process_wrap::tokio::{CommandWrapper, JobObject, KillOnDrop};
#[cfg(unix)] #[cfg(unix)]
use std::os::unix::process::ExitStatusExt; use std::os::unix::process::ExitStatusExt;
use std::sync::Arc; use std::sync::Arc;
@@ -18,9 +18,24 @@ use tokio::{
}; };
use tokio_stream::wrappers::ReceiverStream; use tokio_stream::wrappers::ReceiverStream;
use tracing::Instrument; use tracing::Instrument;
#[cfg(windows)]
use windows::Win32::System::Threading::{CREATE_NO_WINDOW, CREATE_SUSPENDED};
use crate::server::get_wsl_config; use crate::server::get_wsl_config;
#[cfg(windows)]
#[derive(Clone, Copy, Debug)]
// Keep this as a custom wrapper instead of process_wrap::CreationFlags.
// JobObject pre_spawn rewrites creation flags, so this must run after it.
struct WinCreationFlags;
#[cfg(windows)]
impl CommandWrapper for WinCreationFlags {
fn pre_spawn(&mut self, command: &mut Command, _core: &CommandWrap) -> std::io::Result<()> {
command.creation_flags((CREATE_NO_WINDOW | CREATE_SUSPENDED).0);
Ok(())
}
}
const CLI_INSTALL_DIR: &str = ".opencode/bin"; const CLI_INSTALL_DIR: &str = ".opencode/bin";
const CLI_BINARY_NAME: &str = "opencode"; const CLI_BINARY_NAME: &str = "opencode";
@@ -203,7 +218,7 @@ fn get_user_shell() -> String {
} }
fn is_wsl_enabled(_app: &tauri::AppHandle) -> bool { fn is_wsl_enabled(_app: &tauri::AppHandle) -> bool {
get_wsl_config(_app.clone()).is_ok_and(|v| v.enabled) get_wsl_config(_app.clone()).is_ok_and(|v| v.enabled)
} }
fn shell_escape(input: &str) -> String { fn shell_escape(input: &str) -> String {
@@ -318,9 +333,6 @@ pub fn spawn_command(
cmd.stderr(Stdio::piped()); cmd.stderr(Stdio::piped());
cmd.stdin(Stdio::null()); cmd.stdin(Stdio::null());
#[cfg(windows)]
cmd.creation_flags(0x0800_0000);
let mut wrap = CommandWrap::from(cmd); let mut wrap = CommandWrap::from(cmd);
#[cfg(unix)] #[cfg(unix)]
@@ -330,7 +342,7 @@ pub fn spawn_command(
#[cfg(windows)] #[cfg(windows)]
{ {
wrap.wrap(JobObject).wrap(KillOnDrop); wrap.wrap(JobObject).wrap(WinCreationFlags).wrap(KillOnDrop);
} }
let mut child = wrap.spawn()?; let mut child = wrap.spawn()?;