From 8239b298a9b43d169c329f61356cb4cd62875541 Mon Sep 17 00:00:00 2001 From: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com> Date: Tue, 28 Jul 2026 16:39:16 +0800 Subject: [PATCH] revert(panel): put the detail panel's tab tiles back at chrome scale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 540255e dropped them to TILE_SIZE_SM to buy width back after the panel's top row overflowed a 200px column, and used the size step to separate the panel's own tabs from the window chrome sharing that row. Both arguments hold. Neither survives what it looks like: a 24px tile with an 11px glyph next to a 32px one with a 13px glyph doesn't read as a layer below, it reads as shrunk — the panel's primary navigation drawn smaller than the two buttons in the corner. The width it was buying comes from MIN_WIDTH instead, which is where that constraint honestly lives. Six 32px boxes, five 2px gaps and two glyph-aligned insets need 214px, so the floor moves 200 → 216. The panel was never usable at 200 anyway; what a tighter floor bought was an overflowing row. Reverts the tile size, the `rounded_md` that tracked it, and the two insets that were switched to their `_sm` variants to match. --- src/ui/right_panel.rs | 34 ++++++++++++++++++++++++---------- src/ui/tab_strip.rs | 31 ++++++++++++++++--------------- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/ui/right_panel.rs b/src/ui/right_panel.rs index 3aa9baa4..86fb6d14 100644 --- a/src/ui/right_panel.rs +++ b/src/ui/right_panel.rs @@ -28,13 +28,25 @@ use std::rc::Rc; use crate::core::config::{Config, RightPanelTab}; use crate::daemon::protocol::PaneProcs; use crate::terminal::git_diff::{self, DiffSnapshot}; -use crate::ui::app::{CONTENT_INSET, TILE_GLYPH_SM, TILE_SIZE_SM, Tty7App, tile_trailing_inset_sm}; +use crate::ui::app::{ + CONTENT_INSET, TILE_GLYPH_SM, TILE_SIZE_SM, Tty7App, tile_trailing_inset, + tile_trailing_inset_sm, +}; use crate::ui::scrollbar::with_vertical_scrollbar; /// Bounds for the panel's width, mirroring the rail's: a floor so the tree never /// becomes an ellipsis parade, and a ceiling as a fraction of the window so a /// persisted value can't swallow the terminal. -pub(crate) const MIN_WIDTH: f32 = 200.; +/// +/// The floor is also what has to seat the panel's top row on macOS, which is the +/// binding constraint: four chrome tiles, the panel toggle and the "⋯" — six +/// 32px boxes, five 2px gaps and the two glyph-aligned insets — need **214px**. +/// A tighter floor doesn't make the panel narrower, it makes that row overflow; +/// the alternative (shrinking the tabs to body scale) was tried and reads as the +/// panel's own navigation being demoted below the two buttons beside it. 216 +/// leaves the row a hair of slack and is still narrower than any window this +/// panel is usable in. +pub(crate) const MIN_WIDTH: f32 = 216.; pub(crate) const MAX_WIDTH_RATIO: f32 = 0.5; /// Width (px) of the resize handle's invisible hit-area, centered on the panel's @@ -246,11 +258,11 @@ impl Tty7App { .on_double_click(|_, window, _| window.titlebar_double_click()) .items_center() .gap(px(2.)) - // `_sm` because the tabs are body-scale tiles now - // (`right_panel_tabs`): the leading inset has to line the - // *glyph* up on `CONTENT_INSET`, and a 24px tile holds its - // glyph a different distance inside the box than a 32px one. - .pl(px(crate::ui::app::tile_trailing_inset_sm())) + // Chrome scale, like the corner controls this row ends + // with (`right_panel_tabs`): the leading inset lines the + // *glyph* up on `CONTENT_INSET`, so it subtracts the + // 32px tile's own padding rather than a 24px one's. + .pl(px(tile_trailing_inset())) .children(self.right_panel_tabs(cx)) .child(div().flex_1()) // The panel is what reaches the window's right edge while @@ -410,10 +422,12 @@ impl Tty7App { .items_center() .pl(px(CONTENT_INSET)) // Trailing tiles align on the glyph like every other control in the - // window; a label-only header just takes the plain inset. `_SM` covers - // both tile cases now — the tab tiles are body-scale too. + // window; a label-only header just takes the plain inset. `_SM` for a + // tab's own control, whose glyph sits a different distance inside its + // box than the chrome-scale tab tiles do. .pr(px(match (&tabs, has_trailing) { - (Some(_), _) | (None, true) => tile_trailing_inset_sm(), + (Some(_), _) => tile_trailing_inset(), + (None, true) => tile_trailing_inset_sm(), (None, false) => CONTENT_INSET, })) // The line that separates the header from the tab's content. Only diff --git a/src/ui/tab_strip.rs b/src/ui/tab_strip.rs index d788588e..12dd7224 100644 --- a/src/ui/tab_strip.rs +++ b/src/ui/tab_strip.rs @@ -624,16 +624,22 @@ impl Tty7App { /// The detail panel's tab tiles — icon-only, one per view. Lives here beside /// the rest of the chrome tiles so all of them share one styling helper. /// - /// Body scale ([`TILE_SIZE_SM`]), not chrome scale. Two reasons, and the - /// second is why it changed: these tiles live *inside* a panel, which is what - /// that constant is for; and the row they sit in also carries the window's - /// own chrome at its trailing edge, so drawing both at 32px made seven - /// identical squares out of controls belonging to three different layers. - /// One size step is what separates "the panel's own tabs" from "the window's - /// buttons" without adding a rule or a divider. It also buys back the 32px - /// that made the row overflow a 200px-wide panel. + /// **Chrome scale**, like everything else in that row. These were briefly + /// dropped to body scale ([`TILE_SIZE_SM`]) to buy width back after the row + /// overflowed a 200px panel — the tiles live inside a panel, and one size + /// step separates them from the window chrome beside them without spending a + /// divider on it. Both arguments hold; neither survives what it looks like. + /// A 24px tile carrying an 11px glyph next to a 32px one carrying a 13px + /// glyph doesn't read as a layer below, it reads as shrunk — the panel's + /// primary navigation, drawn smaller than the two buttons in the corner. + /// + /// The width the shrink was buying is bought by [`MIN_WIDTH`] instead: the + /// row needs 214px at this scale, so the panel's floor is what has to move. + /// That is the honest place for the constraint anyway — the tiles are as big + /// as they are, and the panel is as narrow as it can afford to be. /// /// [`TILE_SIZE_SM`]: crate::ui::app::TILE_SIZE_SM + /// [`MIN_WIDTH`]: crate::ui::right_panel::MIN_WIDTH pub(crate) fn right_panel_tabs(&self, cx: &mut Context) -> Vec { let active_tab = self.right_panel_tab; // Changed-file count, carried in the Changes tooltip. It used to be a @@ -681,17 +687,12 @@ impl Tty7App { .occlude() .flex_shrink_0() .child( - chrome_tile_sized( + chrome_tile( Button::new(("right-panel-tab", tab as usize)).icon(icon), - crate::ui::app::TILE_SIZE_SM, - crate::ui::app::TILE_GLYPH_SM, active_tab == tab, cx, ) - // `rounded_md` against the chrome tiles' `rounded_lg`: the - // corner radius tracks the box, or a 24px tile reads as a - // 32px one with its sides shaved off. - .rounded_md() + .rounded_lg() .tooltip(match (tab, changed) { (RightPanelTab::Changes, Some(n)) => { SharedString::from(format!("{label} · {n}"))