windows: Prevent command line from opening in release mode (#9839)

Jason Wen and 白山風露 created

Release Notes:

- Prevents the terminal from opening on release mode on Windows

Note: this also prevents Zed from logging to the terminal when it is
launched from the terminal. Is this expected behaviour on other
platforms?

---------

Co-authored-by: 白山風露 <shirayama.kazatsuyu@gmail.com>

Change summary

Cargo.lock             |  1 +
crates/lsp/Cargo.toml  |  3 +++
crates/lsp/src/lsp.rs  | 13 ++++++++++---
crates/zed/src/main.rs |  2 ++
4 files changed, 16 insertions(+), 3 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -5570,6 +5570,7 @@ dependencies = [
  "serde_json",
  "smol",
  "util",
+ "windows 0.53.0",
 ]
 
 [[package]]

crates/lsp/Cargo.toml 🔗

@@ -31,6 +31,9 @@ smol.workspace = true
 util.workspace = true
 release_channel.workspace = true
 
+[target.'cfg(windows)'.dependencies]
+windows.workspace = true
+
 [dev-dependencies]
 async-pipe = { git = "https://github.com/zed-industries/async-pipe-rs", rev = "82d00a04211cf4e1236029aa03e6b6ce2a74c553" }
 ctor.workspace = true

crates/lsp/src/lsp.rs 🔗

@@ -15,6 +15,10 @@ use smol::{
     io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader},
     process::{self, Child},
 };
+
+#[cfg(target_os = "windows")]
+use smol::process::windows::CommandExt;
+
 use std::{
     ffi::OsString,
     fmt,
@@ -215,15 +219,18 @@ impl LanguageServer {
             &binary.arguments
         );
 
-        let mut server = process::Command::new(&binary.path)
+        let mut command = process::Command::new(&binary.path);
+        command
             .current_dir(working_dir)
             .args(binary.arguments)
             .envs(binary.env.unwrap_or_default())
             .stdin(Stdio::piped())
             .stdout(Stdio::piped())
             .stderr(Stdio::piped())
-            .kill_on_drop(true)
-            .spawn()?;
+            .kill_on_drop(true);
+        #[cfg(windows)]
+        command.creation_flags(windows::Win32::System::Threading::CREATE_NO_WINDOW.0);
+        let mut server = command.spawn()?;
 
         let stdin = server.stdin.take().unwrap();
         let stdout = server.stdout.take().unwrap();

crates/zed/src/main.rs 🔗

@@ -1,5 +1,7 @@
 // Allow binary to be called Zed for a nice application menu when running executable directly
 #![allow(non_snake_case)]
+// Disable command line from opening on release mode
+#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
 
 mod zed;