From 367cd759636225affd1df3d10afc1199dbbb56e7 Mon Sep 17 00:00:00 2001 From: Shuhei Kadowaki <40514306+aviatesk@users.noreply.github.com> Date: Thu, 16 Jul 2026 08:21:16 +0900 Subject: [PATCH] workspace: Add visual indicator for editor zoom (#61039) The earlier editor-only zoom implementation in #32860 rendered the active pane with padding, a border, rounded corners, and a shadow. In addition to keeping docks visible, that treatment made the transient editor zoom mode apparent. The current `ToggleEditorZoom` implementation (#53911) only omits sibling panes from the pane group, without any visual indication. Without a persistent control or decoration, the result can look like an ordinary single-pane layout, so users cannot tell whether toggling the command will restore hidden splits. So this commit renders the maximized pane as an inset card with padding, a subtle theme border, rounded corners, and a shadow. Keeping this treatment in `PaneGroup` makes it apply only to editor zoom, leaves docks untouched, and distinguishes it from `ToggleZoom`'s square workspace overlay. ## Showcase Screenshot 2026-07-15 at 18 51 30 --- Release Notes: - N/A --------- Co-authored-by: Danilo Leal --- crates/workspace/src/pane_group.rs | 52 +++++++++++++++++++----------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index dcd0b091a3f..3b0d07dcf25 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -545,39 +545,55 @@ impl Member { }; } - if let Some(maximized) = maximized { + let is_maximized = if let Some(maximized) = maximized { if maximized.upgrade().as_ref() != Some(pane) { return PaneRenderResult { element: div().into_any(), contains_active_pane: false, }; } - } + true + } else { + false + }; let decoration = render_cx.decorate(pane, cx); let is_active = pane == render_cx.active_pane(); + let pane = div() + .relative() + .size_full() + .when(is_maximized, |this| { + this.bg(cx.theme().colors().background) + .border_1() + .border_color(cx.theme().colors().border) + .shadow_lg() + .overflow_hidden() + }) + .child( + AnyView::from(pane.clone()) + .cached(StyleRefinement::default().v_flex().size_full()), + ) + .when_some(decoration.border, |this, color| { + this.child( + div() + .absolute() + .size_full() + .left_0() + .top_0() + .border_2() + .border_color(color), + ) + }) + .children(decoration.status_box); + PaneRenderResult { element: div() .relative() .flex_1() .size_full() - .child( - AnyView::from(pane.clone()) - .cached(StyleRefinement::default().v_flex().size_full()), - ) - .when_some(decoration.border, |this, color| { - this.child( - div() - .absolute() - .size_full() - .left_0() - .top_0() - .border_2() - .border_color(color), - ) - }) - .children(decoration.status_box) + .when(is_maximized, |this| this.p_2()) + .child(pane) .into_any(), contains_active_pane: is_active, }