Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/title_bar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ channel.workspace = true
chrono.workspace = true
client.workspace = true
cloud_api_types.workspace = true
command_palette_hooks.workspace = true
db.workspace = true

git_ui.workspace = true
Expand Down
84 changes: 60 additions & 24 deletions crates/title_bar/src/title_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use auto_update::AutoUpdateStatus;
use call::ActiveCall;
use client::{Client, UserStore, zed_urls};
use cloud_api_types::Plan;
use command_palette_hooks::CommandPaletteFilter;

use gpui::{
Action, Anchor, Animation, AnimationExt, AnyElement, App, Context, Element, Entity, Focusable,
Expand All @@ -38,8 +39,9 @@ use project::{
trusted_worktrees::TrustedWorktrees,
};
use remote::RemoteConnectionOptions;
use settings::Settings as _;
use settings::{Settings as _, SettingsStore};

use std::any::TypeId;
use std::sync::Arc;
use std::time::Duration;
use theme::ActiveTheme;
Expand Down Expand Up @@ -77,9 +79,24 @@ actions!(
]
);

actions!(
workspace,
[
/// Switches to the classic, editor-focused panel layout.
UseClassicLayout,
/// Switches to the agentic panel layout.
UseAgenticLayout,
]
);

pub fn init(cx: &mut App) {
platform_title_bar::PlatformTitleBar::init(cx);

update_layout_action_filter(cx);

cx.observe_global::<SettingsStore>(update_layout_action_filter)
.detach();

cx.observe_new(|workspace: &mut Workspace, window, cx| {
let Some(window) = window else {
return;
Expand All @@ -88,6 +105,14 @@ pub fn init(cx: &mut App) {
let item = cx.new(|cx| TitleBar::new("title-bar", workspace, multi_workspace, window, cx));
workspace.set_titlebar_item(item.into(), window, cx);

workspace.register_action(|_workspace, _: &UseClassicLayout, _window, cx| {
set_window_layout(WindowLayout::Editor(None), cx);
});

workspace.register_action(|_workspace, _: &UseAgenticLayout, _window, cx| {
set_window_layout(WindowLayout::Agent(None), cx);
});

workspace.register_action(|workspace, _: &SimulateUpdateAvailable, _window, cx| {
if let Some(titlebar) = workspace
.titlebar_item()
Expand Down Expand Up @@ -148,6 +173,28 @@ pub fn init(cx: &mut App) {
.detach();
}

/// Hides or shows the panel layout actions in the command palette based on
/// whether AI is currently disabled.
fn update_layout_action_filter(cx: &mut App) {
let disable_ai = project::DisableAiSettings::get_global(cx).disable_ai;
let layout_actions = [
TypeId::of::<UseClassicLayout>(),
TypeId::of::<UseAgenticLayout>(),
];
CommandPaletteFilter::update_global(cx, |filter, _| {
if disable_ai {
filter.hide_action_types(&layout_actions);
} else {
filter.show_action_types(layout_actions.iter());
}
});
}

fn set_window_layout(layout: WindowLayout, cx: &App) {
let fs = <dyn fs::Fs>::global(cx);
drop(AgentSettings::set_layout(layout, fs, cx));
}

pub struct TitleBar {
platform_titlebar: Entity<PlatformTitleBar>,
project: Entity<Project>,
Expand Down Expand Up @@ -1234,7 +1281,6 @@ impl TitleBar {
let is_editor = matches!(current_layout, WindowLayout::Editor(_));
let is_agent = matches!(current_layout, WindowLayout::Agent(_));
let is_custom = matches!(current_layout, WindowLayout::Custom(_));
let fs = <dyn fs::Fs>::global(cx);

ContextMenu::build(window, cx, |menu, _, _cx| {
menu.when(is_signed_in, |this| {
Expand Down Expand Up @@ -1348,36 +1394,26 @@ impl TitleBar {
zed_actions::Extensions::default().boxed_clone(),
)
.when(ai_enabled, |menu| {
let fs = fs.clone();
menu.separator()
.submenu("Panel Layout", move |menu, _window, _cx| {
let fs = fs.clone();
menu.toggleable_entry(
"Classic",
is_editor,
IconPosition::Start,
None,
{
let fs = fs.clone();
move |_window, cx| {
drop(AgentSettings::set_layout(
WindowLayout::Editor(None),
fs.clone(),
cx,
));
}
Some(UseClassicLayout.boxed_clone()),
move |window, cx| {
window.dispatch_action(UseClassicLayout.boxed_clone(), cx);
},
)
.toggleable_entry(
"Agentic",
is_agent,
IconPosition::Start,
Some(UseAgenticLayout.boxed_clone()),
move |window, cx| {
window.dispatch_action(UseAgenticLayout.boxed_clone(), cx);
},
)
.toggleable_entry("Agentic", is_agent, IconPosition::Start, None, {
let fs = fs.clone();
move |_window, cx| {
drop(AgentSettings::set_layout(
WindowLayout::Agent(None),
fs.clone(),
cx,
));
}
})
.when(is_custom, |menu| {
menu.item(
ContextMenuEntry::new("Custom")
Expand Down
Loading