Theming, materials and colour tints
Theme (ui/theme.py) turns a few settings into a
palette of named colour tokens that every widget paints with. There is one instance, returned by theme().
Tokens#
DARK and LIGHT map token names to colours, many of them translucent so the backdrop shows through:
| Token | Used for |
|---|---|
window, sidebar, canvas, card, panel, dialog, layer |
surfaces (translucent) |
*_solid (sidebar_solid, card_solid, …) |
the same surfaces when the material is Solid |
text, text2, text3 |
primary, secondary and tertiary text |
hover, pressed, selected, card_hover |
interaction states |
divider, card_border, input, input_border, focus_ring, shadow, scrim |
lines and effects |
danger, warning, success, sleep |
status colours |
window_tint |
the wash painted over the backdrop |
accent |
the Windows accent colour (or JBrowser blue), adjusted for contrast |
th = theme()
p.fillPath(path, th.surface("card")) # the *_solid variant when the material is Solid
p.setPen(th.c("text2"))
p.setBrush(th.accent_alpha(0.16))
theme().changed fires after every recalculation; widgets repaint on it. Theme.apply() also sets the
application palette and a small style sheet for standard Qt widgets (scroll bars, menus, inputs).
What decides the colours#
refresh() runs at start-up, when the Windows colour scheme changes, and when one of appearance.theme,
appearance.use_accent, appearance.material changes:
- Dark or light:
appearance.theme(system,dark,light);systemfollows Windows. - Accent: the Windows accent colour (
appearance.use_accent), lightened on dark or darkened on light when it would lack contrast. - Material:
appearance.material=acrylic(default),mica,mica_altorsolid. With a translucent material,theme().translucentisTrue: the window paints transparent pixels and DWM draws the system backdrop behind them. Solid paints the opaque*_solidtokens instead.
Fonts#
The UI uses Segoe UI (UI_FONT), and the Segoe UI Variable Display family for large text where available. Icons are
Segoe Fluent Icons glyphs (with a Segoe MDL2 Assets fallback), so no image files are needed.
Changing the look#
- New colour: add a token to both
DARKandLIGHT(and a*_solidvariant if it is a surface), then useth.c("token"). - Never hard-code colours in widgets, except fixed brand colours such as space colours.
- Test both themes, all four materials.