Merge pull request #165 from l0ng-ai/fix/settings-keeps-stock-glyphs

fix(settings): keep the stock glyphs on the Settings page
This commit is contained in:
l0ng-ai
2026-07-25 11:47:43 +08:00
committed by GitHub
2 changed files with 74 additions and 4 deletions
+53 -1
View File
@@ -16,8 +16,23 @@ use gpui::{AssetSource, Result, SharedString};
/// tty7's asset source. Registered once in `main` via `with_assets`.
pub struct Assets;
/// Prefix that opts a single call site *out* of the overrides in [`agent_icon`]
/// and takes gpui-component's own glyph instead: `stock/icons/search.svg`.
///
/// Needed because the overrides are keyed on the asset path, which makes them
/// app-wide (see [`agent_icon`]). Most of them are wanted everywhere, but the
/// detail panel's set is drawn for 18px tiles sitting beside solid dock glyphs,
/// and a few of those shapes are too heavy at the 16px the Settings page uses —
/// its `⋯` in particular, whose filled `r=2` dots smear into three blobs there.
/// Rather than fork the whole set under a second name, those call sites ask for
/// stock by path.
const STOCK_PREFIX: &str = "stock/";
impl AssetSource for Assets {
fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>> {
if let Some(downstream) = path.strip_prefix(STOCK_PREFIX) {
return gpui_component_assets::Assets.load(downstream);
}
if let Some(bytes) = agent_icon(path) {
return Ok(Some(Cow::Borrowed(bytes)));
}
@@ -43,7 +58,8 @@ impl AssetSource for Assets {
/// tty7's and gpui-component's own — resolves through the arm below. Adding a
/// name that upstream also ships redraws it everywhere; check the call sites
/// before doing so, and prefer a name upstream *doesn't* use (`circle-info`)
/// when only one place should change.
/// when only one place should change. A call site that wants the downstream
/// glyph despite an override here asks for it by [`STOCK_PREFIX`].
fn agent_icon(path: &str) -> Option<&'static [u8]> {
let bytes: &'static [u8] = match path {
// Flush `>_` prompt glyph for the plain-shell tab avatar (Lucide's
@@ -133,3 +149,39 @@ fn agent_icon(path: &str) -> Option<&'static [u8]> {
};
Some(bytes)
}
#[cfg(test)]
mod tests {
use super::*;
/// The Settings page reaches for stock glyphs by path; if that stopped
/// bypassing the overrides it would silently pick up the detail panel's
/// heavier redraws again, which is the regression this prefix exists to undo.
#[test]
fn stock_prefix_bypasses_the_overrides() {
for name in ["search", "ellipsis"] {
let overridden = Assets
.load(&format!("icons/{name}.svg"))
.unwrap()
.expect("tty7 override present");
let stock = Assets
.load(&format!("{STOCK_PREFIX}icons/{name}.svg"))
.unwrap()
.expect("downstream glyph present");
assert_ne!(
overridden, stock,
"`{name}` should resolve to different art with and without `{STOCK_PREFIX}`"
);
}
}
/// A `stock/` path for a glyph tty7 never overrode still has to resolve —
/// the prefix is a bypass, not a separate asset set.
#[test]
fn stock_prefix_works_for_unoverridden_glyphs() {
assert_eq!(
Assets.load("stock/icons/check.svg").unwrap(),
Assets.load("icons/check.svg").unwrap(),
);
}
}
+21 -3
View File
@@ -796,7 +796,15 @@ impl Tty7App {
h_flex()
.items_center()
.gap_1()
.child(Icon::new(IconName::Search).small().text_color(header_muted))
// Stock magnifier, not tty7's: this page's glyphs run at
// 16px, where the detail panel's redraw reads thin and
// its handle stubby. See `assets::STOCK_PREFIX`.
.child(
Icon::empty()
.path("stock/icons/search.svg")
.small()
.text_color(header_muted),
)
.child(
div()
.flex_1()
@@ -1695,7 +1703,11 @@ impl Tty7App {
})
.child(
Button::new(("ssh-prof-menu", row_idx))
.icon(IconName::Ellipsis)
// Stock `⋯`, not tty7's: the redraw's filled
// `r=2` dots are weighted for the title bar's
// 18px tiles and smear into three blobs at the
// 16px `small()` uses. See `assets::STOCK_PREFIX`.
.icon(Icon::empty().path("stock/icons/ellipsis.svg"))
.ghost()
.small()
.dropdown_menu_with_anchor(
@@ -3618,7 +3630,13 @@ impl Tty7App {
div().w(px(268.)).child(
Input::new(&search)
.small()
.prefix(Icon::new(IconName::Search).small().text_color(muted_fg)),
// Stock magnifier — same reason as the page header's.
.prefix(
Icon::empty()
.path("stock/icons/search.svg")
.small()
.text_color(muted_fg),
),
),
);