From cd2248f76e6701b83c6939449646d424d5edc5d0 Mon Sep 17 00:00:00 2001
From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
Date: Fri, 24 Apr 2026 09:47:15 -0300
Subject: [PATCH] title_bar: Add "panel layout" menu to the user menu (#54771)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Closes https://github.com/zed-industries/zed/issues/54545
With the release of the parallel agents feature, we changed the default
panel positions optimizing for an agentic-first layout. Even though we
introduced a settings backfill _and_ the ability to revert after
interacting with the announcement toast, this change seems to be causing
a bit of frustration still. In response, this PR adds a "Panel Layout"
menu in the user menu that allows to quickly toggle between the
"Classic" layout and the "Agentic" layout. If you have a different set
up, you'll see a "custom" item there just confirming that.
| Panel Layout | Custom set up |
|--------|--------|
|
|
|
Release Notes:
- Added a menu item in the user menu called "Panel Layout" which offers
the ability to quickly swap between the two standard panel layouts:
classic (project panel, git panel, etc., on the left) and agentic (agent
panel on the left, everything else on the right).
---
Cargo.lock | 2 ++
crates/title_bar/Cargo.toml | 2 ++
crates/title_bar/src/title_bar.rs | 52 +++++++++++++++++++++++++++++--
3 files changed, 54 insertions(+), 2 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 5c2781c649d..61c724c2739 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -18159,6 +18159,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
name = "title_bar"
version = "0.1.0"
dependencies = [
+ "agent_settings",
"anyhow",
"arrayvec",
"auto_update",
@@ -18168,6 +18169,7 @@ dependencies = [
"client",
"cloud_api_types",
"db",
+ "fs",
"git_ui",
"gpui",
"icons",
diff --git a/crates/title_bar/Cargo.toml b/crates/title_bar/Cargo.toml
index ed7b64c3c18..f4850fe5c8a 100644
--- a/crates/title_bar/Cargo.toml
+++ b/crates/title_bar/Cargo.toml
@@ -29,8 +29,10 @@ test-support = [
]
[dependencies]
+agent_settings.workspace = true
anyhow.workspace = true
auto_update.workspace = true
+fs.workspace = true
platform_title_bar.workspace = true
call.workspace = true
channel.workspace = true
diff --git a/crates/title_bar/src/title_bar.rs b/crates/title_bar/src/title_bar.rs
index 8edfca67349..988c8a7c6f4 100644
--- a/crates/title_bar/src/title_bar.rs
+++ b/crates/title_bar/src/title_bar.rs
@@ -7,6 +7,7 @@ mod update_version;
use crate::application_menu::{ApplicationMenu, show_menus};
use crate::plan_chip::PlanChip;
+use agent_settings::{AgentSettings, WindowLayout};
use arrayvec::ArrayVec;
use git_ui::worktree_picker::WorktreePicker;
pub use platform_title_bar::{
@@ -44,8 +45,8 @@ use std::time::Duration;
use theme::ActiveTheme;
use title_bar_settings::TitleBarSettings;
use ui::{
- Avatar, ButtonLike, ContextMenu, IconWithIndicator, Indicator, PopoverMenu, PopoverMenuHandle,
- TintColor, Tooltip, prelude::*, utils::platform_title_bar_height,
+ Avatar, ButtonLike, ContextMenu, ContextMenuEntry, IconWithIndicator, Indicator, PopoverMenu,
+ PopoverMenuHandle, TintColor, Tooltip, prelude::*, utils::platform_title_bar_height,
};
use update_version::UpdateVersion;
use util::ResultExt;
@@ -1202,6 +1203,13 @@ impl TitleBar {
let organizations = organizations.clone();
let user_store = user_store.clone();
+ let ai_enabled = !project::DisableAiSettings::get_global(cx).disable_ai;
+ let current_layout = AgentSettings::get_layout(cx);
+ 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 = ::global(cx);
+
ContextMenu::build(window, cx, |menu, _, _cx| {
menu.when(is_signed_in, |this| {
let user_login = user_login.clone();
@@ -1311,6 +1319,46 @@ impl TitleBar {
"Extensions",
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,
+ ));
+ }
+ },
+ )
+ .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")
+ .toggleable(IconPosition::Start, true)
+ .disabled(true),
+ )
+ })
+ })
+ })
.when(is_signed_in, |this| {
this.separator()
.action("Sign Out", client::SignOut.boxed_clone())