From 11edacfd0f8adde4f8d554598b405b65ac8b7605 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Tue, 14 Apr 2026 09:56:03 -0700 Subject: [PATCH] cli: Defer app activation until after open-behavior prompt (#53915) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On macOS, the CLI uses `LSOpenFromURLSpec` to deliver the `zed-cli://` URL to the running Zed app. With `kLSLaunchDefaults`, Launch Services activates (brings to foreground) the Zed app as a side effect of URL delivery. This happens before the IPC handshake completes and before the user can answer the terminal prompt asking whether to open in a new window or existing workspace, forcing them to manually switch back to the terminal. ## Fix **CLI side** (`crates/cli/src/main.rs`): Add `kLSLaunchDontSwitch` to the launch flags so macOS delivers the URL without activating the app. **App side** (`crates/zed/src/zed/open_listener.rs`): Add `cx.activate(true)` in `handle_cli_connection` after the prompt resolves (or immediately for the URL-only path), so the app comes to the foreground at the right time. Linux and Windows are unaffected — they use Unix sockets and named pipes respectively, which don't have activation side effects. Release Notes: - Fixed the Zed CLI activating the app window before the user answers the open-behavior prompt in the terminal. --- crates/cli/src/main.rs | 6 ++++-- crates/zed/src/zed/open_listener.rs | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 49129532603625b48ac86ba506ad3ff1014f30d3..520f6e6cf2e05595a2f35b194cb65ffe135b4814 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1217,7 +1217,9 @@ mod mac_os { string::kCFStringEncodingUTF8, url::{CFURL, CFURLCreateWithBytes}, }; - use core_services::{LSLaunchURLSpec, LSOpenFromURLSpec, kLSLaunchDefaults}; + use core_services::{ + LSLaunchURLSpec, LSOpenFromURLSpec, kLSLaunchDefaults, kLSLaunchDontSwitch, + }; use serde::Deserialize; use std::{ ffi::OsStr, @@ -1316,7 +1318,7 @@ mod mac_os { appURL: app_url.as_concrete_TypeRef(), itemURLs: urls_to_open.as_concrete_TypeRef(), passThruParams: ptr::null(), - launchFlags: kLSLaunchDefaults, + launchFlags: kLSLaunchDefaults | kLSLaunchDontSwitch, asyncRefCon: ptr::null_mut(), }, ptr::null_mut(), diff --git a/crates/zed/src/zed/open_listener.rs b/crates/zed/src/zed/open_listener.rs index e1a98e62a0f3384fbf003cb0705de1b0bb957d75..aa55ef543802a7271f2a3c935b14b6cedd26e767 100644 --- a/crates/zed/src/zed/open_listener.rs +++ b/crates/zed/src/zed/open_listener.rs @@ -482,6 +482,7 @@ pub async fn handle_cli_connection( cx, ) { Ok(open_request) => { + cx.activate(true); handle_open_request(open_request, app_state.clone(), cx); responses.send(CliResponse::Exit { status: 0 }).log_err(); } @@ -518,6 +519,8 @@ pub async fn handle_cli_connection( } } + cx.update(|cx| cx.activate(true)); + let open_workspace_result = open_workspaces( paths, diff_paths,