diff --git a/crates/remote_desktop_view/src/view.rs b/crates/remote_desktop_view/src/view.rs index 5f938e974..fb10bea4e 100644 --- a/crates/remote_desktop_view/src/view.rs +++ b/crates/remote_desktop_view/src/view.rs @@ -877,6 +877,12 @@ impl RemoteDesktopView { cx: &mut Context, ) -> Self { let manage_native_cursor = config.options.protocol == RemoteDesktopProtocol::Rdp; + // Standalone windows (tab_index: None, e.g. the fullscreen RDP popup) + // have no tab container to drive TabContent::on_activate, so they must + // start as the active presentation and request native focus directly. + // Otherwise the native overlay stays hidden and the window renders + // only the GPUI background. + let standalone_window = config.tab_index.is_none(); let presentation_initialization = if config.options.protocol == RemoteDesktopProtocol::Vnc { presentation::RemoteDesktopPresentationInitialization::Canvas { fallback_reason: None, @@ -1104,7 +1110,7 @@ impl RemoteDesktopView { _presentation_task: None, _presentation_pacing_task: None, presentation_initialization, - tab_active: false, + tab_active: standalone_window, #[cfg(all(feature = "windows-native-rdp", target_os = "windows"))] windows_native: None, #[cfg(all(feature = "windows-native-rdp", target_os = "windows"))] @@ -1126,7 +1132,7 @@ impl RemoteDesktopView { #[cfg(all(feature = "windows-native-rdp", target_os = "windows"))] windows_native_lifecycle_dirty: false, #[cfg(all(feature = "windows-native-rdp", target_os = "windows"))] - windows_native_focus_requested: false, + windows_native_focus_requested: standalone_window, #[cfg(all(feature = "windows-native-rdp", target_os = "windows"))] windows_native_close_requested: false, #[cfg(all(feature = "windows-native-rdp", target_os = "windows"))] diff --git a/crates/remote_desktop_view/src/view/render_contract_tests.rs b/crates/remote_desktop_view/src/view/render_contract_tests.rs index 1f2b5ce20..569ecabdd 100644 --- a/crates/remote_desktop_view/src/view/render_contract_tests.rs +++ b/crates/remote_desktop_view/src/view/render_contract_tests.rs @@ -1443,6 +1443,34 @@ fn windows_native_tab_lifecycle_defers_focus_only_while_active() { } } +#[test] +fn standalone_window_starts_active_with_native_focus_requested() { + let view = include_str!("../view.rs").replace("\r\n", "\n"); + let new_body = function_body( + &view, + "pub fn new(", + "fn cancel_presentation_pacing", + ); + + let standalone = new_body + .find("let standalone_window = config.tab_index.is_none();") + .expect("standalone window detection"); + let tab_active = new_body + .find("tab_active: standalone_window,") + .expect("standalone windows start active"); + let focus_requested = new_body + .find("windows_native_focus_requested: standalone_window,") + .expect("standalone windows request native focus"); + assert!( + standalone < tab_active && tab_active < focus_requested, + "standalone detection must precede both activation intents" + ); + assert!( + !new_body[standalone..tab_active].contains("tab_active: false"), + "initialization must never hard-code the inactive tab state" + ); +} + #[test] fn local_pointer_move_makes_the_canvas_cursor_paintable_before_hiding_native_cursor() { let input = include_str!("input.rs"); diff --git a/main/src/home/home_strategy.rs b/main/src/home/home_strategy.rs index f04c58728..d22544354 100644 --- a/main/src/home/home_strategy.rs +++ b/main/src/home/home_strategy.rs @@ -271,13 +271,8 @@ impl ConnectionOpenStrategy for RemoteDesktopOpenStrategy { connection, protocol, } = *self; - if protocol == RemoteDesktopProtocol::Rdp && remote_desktop::windows_native_rdp_compiled() { - // Windows 原生 RDP 与 gpui-rdp-smoke 一致:在独立全屏窗口中 - // 承载原生 ActiveX child(覆盖整个客户区),避免在主窗口 tab - // 内嵌时被 DirectComposition visual 盖住而白屏。 - home.open_remote_desktop_fullscreen_window(&connection, window, cx); - return; - } + // 双击等常规打开一律走 tab;独立全屏窗口仅保留在连接的右键菜单里 + // (Connection.open_in_fullscreen_window)。 extension_runtime::remote_desktop_provider_install::open_remote_desktop_connection_with_provider_guard( home, connection, protocol, mode, window, cx, ); @@ -301,7 +296,7 @@ mod tests { use one_core::storage::{MongoDBParams, MongoDriverVariant, StoredConnection}; #[test] - fn native_rdp_opens_in_an_independent_window_like_gpui_rdp_smoke() { + fn remote_desktop_double_click_opens_in_a_tab() { let source = include_str!("home_strategy.rs").replace("\r\n", "\n"); let start = source .find("impl ConnectionOpenStrategy for RemoteDesktopOpenStrategy") @@ -312,13 +307,14 @@ mod tests { .expect("next strategy"); let strategy = &source[start..end]; - assert!(strategy.contains("protocol == RemoteDesktopProtocol::Rdp")); - assert!(strategy.contains("remote_desktop::windows_native_rdp_compiled()")); assert!( - strategy - .contains("home.open_remote_desktop_fullscreen_window(&connection, window, cx)") + strategy.contains("open_remote_desktop_connection_with_provider_guard("), + "double-click must open the remote desktop in a tab" + ); + assert!( + !strategy.contains("open_remote_desktop_fullscreen_window"), + "the fullscreen window must stay behind the context-menu action" ); - assert!(strategy.contains("open_remote_desktop_connection_with_provider_guard(")); } #[test]