From cb5e35f7cbfe09aba11af752eea879de59db681e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=B7=E7=94=B5=E8=8A=BD=E8=A1=A3?= Date: Thu, 8 Oct 2026 21:55:55 -0400 Subject: [PATCH] CI: fmt the narrow-layout commits, and Theme::hairline in place of their raw px --- src/buttons/segmented.rs | 15 +++++++++------ src/forms/switch.rs | 4 +++- src/layout/narrow.rs | 10 ++++++++-- src/navigation/tabs.rs | 19 ++++++++++++++----- src/shell/bars.rs | 12 ++++++++++-- src/shell/status.rs | 23 +++++++++++++++++++---- src/theme/tokens.rs | 5 +++++ tasks/github.md | 2 +- 8 files changed, 69 insertions(+), 21 deletions(-) diff --git a/src/buttons/segmented.rs b/src/buttons/segmented.rs index ee31d34..6f65d6f 100644 --- a/src/buttons/segmented.rs +++ b/src/buttons/segmented.rs @@ -3,8 +3,7 @@ use std::rc::Rc; use gpui::{ Animation, AnimationExt, AnyElement, App, ElementId, FocusHandle, FontWeight, InteractiveElement, IntoElement, MouseButton, ParentElement, Pixels, RenderOnce, Role, - ScrollHandle, SharedString, StatefulInteractiveElement, Styled, Window, div, prelude::*, px, - rems, + ScrollHandle, SharedString, StatefulInteractiveElement, Styled, Window, div, prelude::*, rems, }; use super::button::label_size; @@ -96,7 +95,8 @@ impl RenderOnce for SegmentedControl { }) .collect(); // Last frame's strip width decides icons only. - let strip = window.use_keyed_state((self.id.clone(), "strip-width"), cx, |_, _| Pixels::ZERO); + let strip = + window.use_keyed_state((self.id.clone(), "strip-width"), cx, |_, _| Pixels::ZERO); let shown = *strip.read(cx); let compact = self.segments.iter().all(|(_, _, icon)| icon.is_some()) && shown > Pixels::ZERO @@ -189,7 +189,9 @@ impl RenderOnce for SegmentedControl { .when_some(icon, |segment, icon| { segment.child(Icon::new(icon).size(icon_size).color(fg)) }) - .when(compact, |segment| segment.tooltip(Tooltip::text(label.clone()))) + .when(compact, |segment| { + segment.tooltip(Tooltip::text(label.clone())) + }) .when(!label.is_empty() && !compact, |segment| { segment.child( div() @@ -246,9 +248,10 @@ fn natural( let theme = cx.theme(); let rem = window.rem_size(); let (text, icon) = label_size(size); - let pad = theme.control_padding(size).to_pixels(rem) * 2.0 + px(2.0); + let pad = (theme.control_padding(size).to_pixels(rem) + theme.hairline()) * 2.0; let glyph = theme.icon_size(icon).to_pixels(rem) + rems(0.375).to_pixels(rem); - segments.iter().fold(px(6.0), |sum, (_, label, icon)| { + let strip = (rems(0.125).to_pixels(rem) + theme.hairline()) * 2.0; + segments.iter().fold(strip, |sum, (_, label, icon)| { let width = text_width(label, text, FontWeight::SEMIBOLD, window, cx); sum + pad + width + if icon.is_some() { glyph } else { Pixels::ZERO } }) diff --git a/src/forms/switch.rs b/src/forms/switch.rs index 2b412fa..1b39195 100644 --- a/src/forms/switch.rs +++ b/src/forms/switch.rs @@ -129,7 +129,9 @@ impl RenderOnce for Switch { .id(self.id) .role(Role::Switch) .aria_toggled(self.on.into()) - .when_some(self.label.clone().or(self.name), |row, label| row.aria_label(label)) + .when_some(self.label.clone().or(self.name), |row, label| { + row.aria_label(label) + }) .when(self.disabled, |row| { row.aria_description(i18n::text(cx, "state.unavailable", &[])) }) diff --git a/src/layout/narrow.rs b/src/layout/narrow.rs index ce64704..2843564 100644 --- a/src/layout/narrow.rs +++ b/src/layout/narrow.rs @@ -18,13 +18,19 @@ pub(crate) fn text_width( let font_size = cx.theme().text_size(size).to_pixels(window.rem_size()); let run = TextRun { len: text.len(), - font: Font { weight, ..window.text_style().font() }, + font: Font { + weight, + ..window.text_style().font() + }, color: Hsla::default(), background_color: None, underline: None, strikethrough: None, }; - window.text_system().shape_line(text.clone(), font_size, &[run], None).width + window + .text_system() + .shape_line(text.clone(), font_size, &[run], None) + .width } /// Keeps `width` at the parent's width; a change redraws once. diff --git a/src/navigation/tabs.rs b/src/navigation/tabs.rs index d54eac2..b6d1671 100644 --- a/src/navigation/tabs.rs +++ b/src/navigation/tabs.rs @@ -218,7 +218,9 @@ impl RenderOnce for Tabs { .when_some(tab.icon, |item, icon| { item.child(Icon::new(icon).size(IconSize::Sm).color(fg)) }) - .when(compact, |item| item.tooltip(Tooltip::text(tab.label.clone()))) + .when(compact, |item| { + item.tooltip(Tooltip::text(tab.label.clone())) + }) .when(!compact, |item| item.child(tab.label.clone())) .when_some(tab.note.clone().filter(|_| !compact), |item, note| { item.child(div().text_color(colors.fg_subtle).child(note)) @@ -293,13 +295,20 @@ impl RenderOnce for Tabs { fn natural(tabs: &[Choice], window: &Window, cx: &App) -> Pixels { let theme = cx.theme(); let rem = window.rem_size(); - let pad = gpui::rems(0.75).to_pixels(rem) * 2.0 + gpui::px(2.0); + let pad = (gpui::rems(0.75).to_pixels(rem) + theme.hairline()) * 2.0; let glyph = theme.icon_size(IconSize::Sm).to_pixels(rem) + gpui::rems(0.375).to_pixels(rem); let gap = gpui::rems(0.25).to_pixels(rem); tabs.iter().fold(Pixels::ZERO, |sum, tab| { - let text = |text: &SharedString| text_width(text, TextSize::Sm, FontWeight::MEDIUM, window, cx); - let note = tab.note.as_ref().map_or(Pixels::ZERO, |note| text(note) + gpui::rems(0.375).to_pixels(rem)); - let icon = if tab.icon.is_some() { glyph } else { Pixels::ZERO }; + let text = + |text: &SharedString| text_width(text, TextSize::Sm, FontWeight::MEDIUM, window, cx); + let note = tab.note.as_ref().map_or(Pixels::ZERO, |note| { + text(note) + gpui::rems(0.375).to_pixels(rem) + }); + let icon = if tab.icon.is_some() { + glyph + } else { + Pixels::ZERO + }; sum + pad + icon + text(&tab.label) + note + gap }) } diff --git a/src/shell/bars.rs b/src/shell/bars.rs index 7d82226..14919b3 100644 --- a/src/shell/bars.rs +++ b/src/shell/bars.rs @@ -6,9 +6,9 @@ use gpui::{ use smallvec::SmallVec; use crate::{ - typography::Ellipsis, primitives::{Icon, IconName, Tooltip}, theme::{ActiveTheme, ControlSize, IconSize, Radius, TextSize}, + typography::Ellipsis, }; /// A row of tools, grouped and divided. @@ -145,7 +145,15 @@ impl RenderOnce for StatusBar { fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement { let theme = cx.theme(); // Narrow, both sides shrink and labels end in an ellipsis. - let side = || div().flex().items_center().gap_0p5().h_full().min_w_0().overflow_hidden(); + let side = || { + div() + .flex() + .items_center() + .gap_0p5() + .h_full() + .min_w_0() + .overflow_hidden() + }; self.base .flex() .flex_none() diff --git a/src/shell/status.rs b/src/shell/status.rs index f87c63b..a7d74ef 100644 --- a/src/shell/status.rs +++ b/src/shell/status.rs @@ -184,11 +184,18 @@ pub struct ZoomControl { impl ZoomControl { pub fn new(id: impl Into) -> Self { - Self { id: id.into(), owned: None } + Self { + id: id.into(), + owned: None, + } } /// Shows `percent` and hands each press to `on_zoom`. - pub fn owned(mut self, percent: u32, on_zoom: impl Fn(ZoomStep, &mut Window, &mut App) + 'static) -> Self { + pub fn owned( + mut self, + percent: u32, + on_zoom: impl Fn(ZoomStep, &mut Window, &mut App) + 'static, + ) -> Self { self.owned = Some((percent, Rc::new(on_zoom))); self } @@ -263,7 +270,11 @@ fn owned(id: ElementId, percent: u32, on_zoom: OnZoom, cx: &App) -> impl IntoEle .flex_none() .items_center() .gap_0p5() - .child(IconButton::new("zoom-out", IconName::ZoomOut).size(ControlSize::Sm).on_click(press(ZoomStep::Out))) + .child( + IconButton::new("zoom-out", IconName::ZoomOut) + .size(ControlSize::Sm) + .on_click(press(ZoomStep::Out)), + ) .child( div() .id("zoom-reset") @@ -279,7 +290,11 @@ fn owned(id: ElementId, percent: u32, on_zoom: OnZoom, cx: &App) -> impl IntoEle .child(AnimatedNumber::new("zoom-value", percent as f64).size(TextSize::Sm)) .child(div().text_size(theme.text_size(TextSize::Sm)).child("%")), ) - .child(IconButton::new("zoom-in", IconName::ZoomIn).size(ControlSize::Sm).on_click(press(ZoomStep::In))) + .child( + IconButton::new("zoom-in", IconName::ZoomIn) + .size(ControlSize::Sm) + .on_click(press(ZoomStep::In)), + ) } #[cfg(test)] diff --git a/src/theme/tokens.rs b/src/theme/tokens.rs index b4b700b..f077788 100644 --- a/src/theme/tokens.rs +++ b/src/theme/tokens.rs @@ -179,6 +179,11 @@ impl Theme { px(1.0) } + /// A border's width, which does not scale: `border_1`. + pub fn hairline(&self) -> Pixels { + px(1.0) + } + pub fn caret_width(&self) -> Rems { px_to_rems(1.5) } diff --git a/tasks/github.md b/tasks/github.md index 28f51ea..94a36af 100644 --- a/tasks/github.md +++ b/tasks/github.md @@ -15,7 +15,7 @@ # GitHub round, 2026-10-08 -- [x] G10 CI: `cargo fmt` on the files the last commits left unformatted +- [x] G10 CI: `cargo fmt` on the files the last commits left unformatted; then the narrow-layout commits: fmt, and `Theme::hairline` for their raw px - [x] G11 Issue #7: a caret is a whole number of device pixels wide at a device pixel, so it never shows thin then thick; tested - [x] G12 Issue #7: an IME asks for its candidate box past the laid-out text; the box clamps to the last layout, as `bounds_for` does; tested - [x] G13 Issue #12: a floating option list occludes, so the wheel scrolls the list and not the page under it; tested