From dddd07a3602ae51d1f4456b23b6eed4bce348df5 Mon Sep 17 00:00:00 2001 From: thomas Date: Mon, 27 Jul 2026 09:42:02 +0800 Subject: [PATCH] fix(ui): give the segmented control the surface it actually paints on MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `segmented` paints its own opaque track — deliberately, since every rung above it was derived against that ground. But it hardcoded the window surface, and one of its sixteen call sites is the managed-forward form in the right panel, which is a sunk `sidebar` rail: the track landed as a faintly darker box cut out of the column around it, and its hover / selected / label rungs were measured against a ground that was not there. Split off `segmented_on`, which takes the `Surface`; `segmented` keeps the window default the settings sheet wants. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01WCb8ZDmvdA5xbVtvs647tD --- src/ui/forwards.rs | 6 +++++- src/ui/settings.rs | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/ui/forwards.rs b/src/ui/forwards.rs index c656f96e..804be22c 100644 --- a/src/ui/forwards.rs +++ b/src/ui/forwards.rs @@ -358,6 +358,9 @@ impl Tty7App { fn forward_form(&self, pane_id: u64, cx: &mut Context) -> Div { let theme = cx.theme(); let muted = theme.muted_foreground; + // The form is inside the right panel, i.e. on the sunk rail — not on the + // settings sheet the segmented control otherwise assumes. + let sf = cx.global::().sidebar; let kind = self.loopback_panel.mf_kind; let editing = self.loopback_panel.mf_editing.is_some(); let selected = match kind { @@ -394,7 +397,8 @@ impl Tty7App { .pt(px(6.)) .pb(px(2.)) .gap(px(5.)) - .child(self.segmented( + .child(self.segmented_on( + sf, "ssh-managed-forward-kind", &["Local", "Remote", "Dynamic"], selected, diff --git a/src/ui/settings.rs b/src/ui/settings.rs index ecb54bf5..26aa1c96 100644 --- a/src/ui/settings.rs +++ b/src/ui/settings.rs @@ -1204,6 +1204,23 @@ impl Tty7App { on_pick: impl Fn(&mut Self, usize, &mut Window, &mut Context) + 'static, ) -> AnyElement { let sf = cx.global::().window; + self.segmented_on(sf, id, options, selected, cx, on_pick) + } + + /// [`Self::segmented`] for a control that does *not* sit on the settings + /// sheet. The track paints its own opaque ground, so it has to be told which + /// one: dropped on the right panel's sunk rail, a window-surface track reads + /// as a faintly darker box cut out of the column it sits in — and every rung + /// above it was derived against the wrong ground. + pub(crate) fn segmented_on( + &self, + sf: presets::Surface, + id: &'static str, + options: &'static [&'static str], + selected: usize, + cx: &mut Context, + on_pick: impl Fn(&mut Self, usize, &mut Window, &mut Context) + 'static, + ) -> AnyElement { let border = cx.theme().border; let on_pick = std::rc::Rc::new(on_pick); h_flex()