The stroked icon set
Change: openspec/changes/the-shell-has-one-visual-language, task 4.1.
What changed
glyph.rsis the shell’s own icon set: eleven monochrome glyphs drawn as cairo paths on a 24-unit grid.- Glyphs: Wi‑Fi, sun, small sun, speaker, muted speaker, keyboard, motion, key backlight, reboot, power and search.
- Strokes have round caps and joins. The stroke is 3 px at 48 px
(
glyph::ROW), 4 px at 64 px (glyph::DRAWER), and never under 2 px.
- Where they replace older drawing:
- The slider-end suns and the volume speaker (in Settings and the Shade)
were a filled disc and a filled cone (
paint_sun,paint_speaker). - The volume HUD’s speaker.
- The drawer search glyph, which was an ad hoc circle and line.
- The slider-end suns and the volume speaker (in Settings and the Shade)
were a filled disc and a filled cone (
- New leading glyphs on the Settings rows (Wi‑Fi, Brightness, Volume, Keyboard, Motion, Key backlight), the Reboot and Power off cards, and the Shade’s Keyboard toggle.
- Colour. Every glyph is in the foreground colour; the small sun and the muted speaker are muted. The bright-end sun and the unmuted speaker used to be in the accent; they are now in the foreground colour, in line with the one-accent rule.
- Size: a deviation from design §11. Design §11 gives a fixed 48 px row
icon. A fixed 48 px column with the text beside it cut the Keyboard value
(“On-screen keyb…”) at 100% in the side-by-side layout, and stayed small
beside 200% text.
- Instead, a row’s glyph sits on the label line, sized to 1.3 times that
line’s text and centred on it (
paint_line_glyph). - Only the label line is indented; the value and caption keep the full width.
- This makes the glyph about 34 px at 100% and 68 px at 200%. The 48/64 px sizes are what the test checks.
- Instead, a row’s glyph sits on the label line, sized to 1.3 times that
line’s text and centred on it (
- App icons still come from the theme and are unchanged. That includes the drawer’s 64 px app icons.
Host evidence (2026-10-17)
cargo test --offline --manifest-path nix/rust-shell-client/Cargo.toml --tests:- All targets passed (lib: 574 passed, 2 ignored).
glyph::tests::every_glyph_inks_its_box_at_the_row_and_drawer_sizes_and_stays_insiderenders each glyph at 48 and 64 px. It requires more than 4% and less than 50% of the box to be inked, and no ink outside the box.the_stroke_is_three_pixels_at_the_row_size_and_never_under_twochecks the stroke widths.the_glyphs_are_distinctchecks that no two glyphs render the same.- The accent-group test from 3.3 still passes.
- Pixel-identity baselines. The
docs/evidence/shell-responsive/drawer-*frames were regenerated deliberately for the search glyph. The Settings and Home baselines did not change: their fixture has no services, so it shows “Loading settings”. - Renders.
render_glyph_evidencedrew the glyph sheet, andrender_accessibility_scale_evidencedrew the surfaces, using the catppuccin and catppuccin-latte generations fromdocs/evidence/card-jobs/README.md. Each surface sheet is at 50%.
| File | Content |
|---|---|
host-glyph-sheet.png | Every glyph; rows: dark 48 px, dark 64 px, light 48 px, light 64 px |
host-dark-landscape.png | 1232x568, 2x2: Settings at 100%, 200% (top); Shade at 100%, 200% (bottom) |
host-dark-portrait.png | 568x1232: Settings 100%, 200%; Shade 100%, 200% |
host-latte-*.png | The same in catppuccin-latte |
Limits
- The Volume row’s “No audio device found” was cut off at 200% in portrait.
Fixed afterwards (2026-10-17): the line now uses
themed_role_fitlike the other row values. It shrinks to fit the column, never below the Body role, and a host render oflargest-settings-568x1232shows it whole. - The board captures are below. The operator’s look at the icons (5.2) is separate and still open.
Board evidence (2026-10-17)
- Build.
kernelMainlineDrmShellLandscapeHdmiBootFileswas built at5f244c0cand deployed live withswitch-to-configuration test. The active system was/nix/store/a4241ifl36r41l3ccx24prrsq5p2q1n0-nixos-system-nixos-26.11.20260919.20b1ddd. - Capture. DSI-1 was the only output, at 1232x568 and 100%, with the retro-82 theme.
- Navigation. Surfaces were opened with
k230-shell-rust --surface. Settings was scrolled with an injected uinput swipe (/tmp/bp.py). The frames are nativegrimcaptures.
| File | What it shows |
|---|---|
board-panel-settings.png | Wi‑Fi, Brightness, Keyboard, Motion, Reboot and Power off glyphs |
board-panel-settings-scrolled.png | Volume (40%) with the speaker glyph and slider; Key backlight glyph and level slider |
board-panel-shade.png | Shade: stroked suns and speaker at the slider ends, Keyboard toggle glyph |
- Observation: audio arrives late after a restart. The deploy
restarted PipeWire and the shell together (
shell-uistarted at 01:36:40). The shell’s journal shows its first default-sink snapshot at 69.6 s: the volume HUD opened at 01:37:56. The two Shade captures without a volume slider were mapped at 12.2 s and 43.6 s, before that snapshot. The capture with the slider was mapped at 126.8 s. The missing slider was PipeWire still starting, not a rendering fault.