fix(win32): Sidecar spawning a window#14197
Conversation
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
There was a problem hiding this comment.
Pull request overview
This PR addresses a Windows regression introduced in v1.2.6 where the opencode-cli sidecar process spawns a visible console window. The root cause was that the process-wrap library's JobObject wrapper overwrites creation flags set directly on Command. The fix implements a custom CommandWrapper that applies CREATE_NO_WINDOW after JobObject runs its pre_spawn hook, ensuring the flag is preserved.
Changes:
- Implements custom
WinCreationFlagswrapper to set Windows process creation flags afterJobObjectprocessing - Adds Windows API dependency for
CREATE_NO_WINDOWandCREATE_SUSPENDEDconstants - Removes direct
creation_flagscall that was being overwritten byJobObject
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/desktop/src-tauri/src/cli.rs | Adds custom CommandWrapper implementation and integrates it into wrapper chain after JobObject |
| packages/desktop/src-tauri/Cargo.toml | Adds windows crate dependency for Win32 API constants |
| packages/desktop/src-tauri/Cargo.lock | Updates lock file to reflect new windows dependency |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #[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); |
There was a problem hiding this comment.
The CREATE_SUSPENDED flag causes the process to start in a suspended state and requires an explicit ResumeThread call to begin execution. There is no code in this file that resumes the process after spawning. This will cause the sidecar process to hang indefinitely in a suspended state, making it completely non-functional. Remove CREATE_SUSPENDED from the creation flags and keep only CREATE_NO_WINDOW.
What does this PR do?
Fixes a Windows desktop regression where starting the local
opencode-clisidecar opens a visible console window.Regression timeline (data-driven)
v1.2.4..v1.2.5: no changes topackages/desktop/src-tauri/src/cli.rssidecar spawn path.920255e8c(desktop: use process-wrap instead of manual job object, desktop: use process-wrap instead of manual job object #13431), included inv1.2.6/github-v1.2.16.d338bd528(Hide server CLI on windows, Hide server CLI on windows #13936) attempted to setCREATE_NO_WINDOW, but did not fully resolve the issue.Root cause
When using
process-wrap+JobObjecton Windows, creation flags set directly onCommandcan be overwritten during wrapperpre_spawnhandling, soCREATE_NO_WINDOWmay be lost.Fix approach
Apply Windows creation flags with process-wrap-aware ordering/handling so the spawned sidecar keeps
CREATE_NO_WINDOWwhile preservingJobObjectlifecycle behavior.Verification
packages/desktop/src-tauri/src/cli.rs.process-wrap/src/generic_wrap.rsprocess-wrap/src/tokio/job_object.rsprocess-wrap/src/tokio/creation_flags.rscargo check --target x86_64-pc-windows-msvc(frompackages/desktop/src-tauri)