diff --git a/Cargo.lock b/Cargo.lock index a995f9c5c15ee1f5f2bfcdce20c144c2eb6a2fa8..a9aa6e2303ce4bf15ffe35b0a1a1948e0950d06a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12475,6 +12475,7 @@ version = "0.1.0" dependencies = [ "feature_flags", "gpui", + "project", "settings", "smallvec", "theme", diff --git a/crates/platform_title_bar/Cargo.toml b/crates/platform_title_bar/Cargo.toml index 2f1f6d2cd9297136077780aafdc75d22ecf6b845..43ad6166929bc463edbea878941ba19ffe2ea3a9 100644 --- a/crates/platform_title_bar/Cargo.toml +++ b/crates/platform_title_bar/Cargo.toml @@ -15,6 +15,7 @@ doctest = false [dependencies] feature_flags.workspace = true gpui.workspace = true +project.workspace = true settings.workspace = true smallvec.workspace = true theme.workspace = true diff --git a/crates/platform_title_bar/src/platform_title_bar.rs b/crates/platform_title_bar/src/platform_title_bar.rs index 6f89a5c39137896ee4b1a6cd3b81770fc3382284..7053fe89e7fdc6ece9ad50fdd8facaf31dba3086 100644 --- a/crates/platform_title_bar/src/platform_title_bar.rs +++ b/crates/platform_title_bar/src/platform_title_bar.rs @@ -7,6 +7,8 @@ use gpui::{ MouseButton, ParentElement, StatefulInteractiveElement, Styled, Window, WindowControlArea, div, px, }; +use project::DisableAiSettings; +use settings::Settings; use smallvec::SmallVec; use std::mem; use ui::{ @@ -95,7 +97,7 @@ impl PlatformTitleBar { } pub fn is_multi_workspace_enabled(cx: &App) -> bool { - cx.has_flag::() + cx.has_flag::() && !DisableAiSettings::get_global(cx).disable_ai } } diff --git a/crates/title_bar/src/title_bar.rs b/crates/title_bar/src/title_bar.rs index b52bde3fdb0b0230c271cc99210fdd13e7eac7cc..f00a71a305e306ba9201e5a4976382012ae0059e 100644 --- a/crates/title_bar/src/title_bar.rs +++ b/crates/title_bar/src/title_bar.rs @@ -31,7 +31,9 @@ use gpui::{ StatefulInteractiveElement, Styled, Subscription, WeakEntity, Window, actions, div, }; use onboarding_banner::OnboardingBanner; -use project::{Project, git_store::GitStoreEvent, trusted_worktrees::TrustedWorktrees}; +use project::{ + DisableAiSettings, Project, git_store::GitStoreEvent, trusted_worktrees::TrustedWorktrees, +}; use remote::RemoteConnectionOptions; use settings::Settings; use settings::WorktreeId; @@ -686,7 +688,7 @@ impl TitleBar { _window: &mut Window, cx: &mut Context, ) -> Option { - if !cx.has_flag::() { + if !cx.has_flag::() || DisableAiSettings::get_global(cx).disable_ai { return None; } diff --git a/crates/workspace/src/multi_workspace.rs b/crates/workspace/src/multi_workspace.rs index e5d529556be690298b57fbb864a7010729e8c170..b8651c38b1c6ce54455e0d134acd3777ad285ee4 100644 --- a/crates/workspace/src/multi_workspace.rs +++ b/crates/workspace/src/multi_workspace.rs @@ -5,7 +5,8 @@ use gpui::{ ManagedView, MouseButton, Pixels, Render, Subscription, Task, Tiling, Window, WindowId, actions, deferred, px, }; -use project::Project; +use project::{DisableAiSettings, Project}; +use settings::Settings; use std::future::Future; use std::path::PathBuf; use ui::prelude::*; @@ -122,6 +123,12 @@ impl MultiWorkspace { } }); let quit_subscription = cx.on_app_quit(Self::app_will_quit); + let settings_subscription = + cx.observe_global_in::(window, |this, window, cx| { + if DisableAiSettings::get_global(cx).disable_ai && this.sidebar_open { + this.close_sidebar(window, cx); + } + }); Self::subscribe_to_workspace(&workspace, cx); Self { window_id: window.window_handle().window_id(), @@ -133,7 +140,11 @@ impl MultiWorkspace { pending_removal_tasks: Vec::new(), _serialize_task: None, _create_task: None, - _subscriptions: vec![release_subscription, quit_subscription], + _subscriptions: vec![ + release_subscription, + quit_subscription, + settings_subscription, + ], } } @@ -169,7 +180,7 @@ impl MultiWorkspace { } pub fn multi_workspace_enabled(&self, cx: &App) -> bool { - cx.has_flag::() + cx.has_flag::() && !DisableAiSettings::get_global(cx).disable_ai } pub fn toggle_sidebar(&mut self, window: &mut Window, cx: &mut Context) { @@ -732,16 +743,18 @@ impl Render for MultiWorkspace { this.activate_previous_workspace(window, cx); }, )) - .on_action(cx.listener( - |this: &mut Self, _: &ToggleWorkspaceSidebar, window, cx| { - this.toggle_sidebar(window, cx); - }, - )) - .on_action( - cx.listener(|this: &mut Self, _: &FocusWorkspaceSidebar, window, cx| { - this.focus_sidebar(window, cx); - }), - ) + .when(self.multi_workspace_enabled(cx), |this| { + this.on_action(cx.listener( + |this: &mut Self, _: &ToggleWorkspaceSidebar, window, cx| { + this.toggle_sidebar(window, cx); + }, + )) + .on_action(cx.listener( + |this: &mut Self, _: &FocusWorkspaceSidebar, window, cx| { + this.focus_sidebar(window, cx); + }, + )) + }) .when( self.sidebar_open() && self.multi_workspace_enabled(cx), |this| { @@ -774,3 +787,92 @@ impl Render for MultiWorkspace { ) } } + +#[cfg(test)] +mod tests { + use super::*; + use fs::FakeFs; + use gpui::TestAppContext; + use settings::SettingsStore; + + fn init_test(cx: &mut TestAppContext) { + cx.update(|cx| { + let settings_store = SettingsStore::test(cx); + cx.set_global(settings_store); + theme::init(theme::LoadThemes::JustBase, cx); + DisableAiSettings::register(cx); + cx.update_flags(false, vec!["agent-v2".into()]); + }); + } + + #[gpui::test] + async fn test_sidebar_disabled_when_disable_ai_is_enabled(cx: &mut TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.executor()); + let project = Project::test(fs, [], cx).await; + + let (multi_workspace, cx) = + cx.add_window_view(|window, cx| MultiWorkspace::test_new(project, window, cx)); + + multi_workspace.read_with(cx, |mw, cx| { + assert!(mw.multi_workspace_enabled(cx)); + }); + + multi_workspace.update_in(cx, |mw, _window, cx| { + mw.open_sidebar(cx); + assert!(mw.is_sidebar_open()); + }); + + cx.update(|_window, cx| { + DisableAiSettings::override_global(DisableAiSettings { disable_ai: true }, cx); + }); + cx.run_until_parked(); + + multi_workspace.read_with(cx, |mw, cx| { + assert!( + !mw.is_sidebar_open(), + "Sidebar should be closed when disable_ai is true" + ); + assert!( + !mw.multi_workspace_enabled(cx), + "Multi-workspace should be disabled when disable_ai is true" + ); + }); + + multi_workspace.update_in(cx, |mw, window, cx| { + mw.toggle_sidebar(window, cx); + }); + multi_workspace.read_with(cx, |mw, _cx| { + assert!( + !mw.is_sidebar_open(), + "Sidebar should remain closed when toggled with disable_ai true" + ); + }); + + cx.update(|_window, cx| { + DisableAiSettings::override_global(DisableAiSettings { disable_ai: false }, cx); + }); + cx.run_until_parked(); + + multi_workspace.read_with(cx, |mw, cx| { + assert!( + mw.multi_workspace_enabled(cx), + "Multi-workspace should be enabled after re-enabling AI" + ); + assert!( + !mw.is_sidebar_open(), + "Sidebar should still be closed after re-enabling AI (not auto-opened)" + ); + }); + + multi_workspace.update_in(cx, |mw, window, cx| { + mw.toggle_sidebar(window, cx); + }); + multi_workspace.read_with(cx, |mw, _cx| { + assert!( + mw.is_sidebar_open(), + "Sidebar should open when toggled after re-enabling AI" + ); + }); + } +}