pub struct SystemTheme {
pub name: Cow<'static, str>,
pub mode: ColorMode,
pub light: ResolvedTheme,
pub dark: ResolvedTheme,
pub preset: String,
pub icon_set: IconSet,
pub icon_theme: Option<Cow<'static, str>>,
pub layout: LayoutTheme,
pub accessibility: AccessibilityPreferences,
/* private fields */
}Expand description
Result of the OS-first pipeline. Holds both resolved variants.
Produced by SystemTheme::from_system() and SystemTheme::from_system_async().
Both light and dark are always populated: the OS-active variant
comes from the reader + preset + resolve, the inactive variant
comes from the preset + resolve.
Fields§
§name: Cow<'static, str>Theme name (from reader or preset).
§Ownership type
This field uses Cow<'static, str>, not Arc<str>. The v0.5.7 API
review recommended uniform Arc<str> across name, icon_theme,
ReaderOutput::name, and ResolvedFontSpec::family. The audit in
docs/archive/v0.5.7_gaps.md §G9 concluded that the
uniform recommendation should be adopted ONLY for
ResolvedFontSpec::family
(where 26 widgets × connectors genuinely share font families), and
should be REVERSED for name / icon_theme because:
- Each resolved theme carries exactly ONE
name— no dedup benefit. - Bundled preset names are
&'static strliterals;Cow::Borrowed(static_lit)is zero allocation, zero refcount.Arc<str>would require at least one allocation per unique string at construction time, paying allocation cost for a dedup benefit that is structurally absent.
The same reasoning applies symmetrically to
SystemTheme::icon_theme,
Theme::name, and
ThemeDefaults::icon_theme.
See docs/archive/v0.5.7_gaps.md §G9 for the full audit.
mode: ColorModeThe OS color mode preference (light or dark).
light: ResolvedThemeResolved light variant (always populated).
dark: ResolvedThemeResolved dark variant (always populated).
preset: StringThe platform preset used (e.g., “kde-breeze”, “adwaita”, “macos-sonoma”).
icon_set: IconSetWhich icon loading mechanism to use for this theme.
icon_theme: Option<Cow<'static, str>>The name of the visual icon theme (e.g. "breeze", "Adwaita"):
the active variant’s, else the theme’s, else the detected system
icon theme. None where the theme states none and detection fails;
system_icon_theme() gives the
reason.
§Ownership type
Cow<'static, str> is used here per the same principled deviation
documented on SystemTheme::name — see docs/archive/v0.5.7_gaps.md
§G9. Each resolved theme carries a single icon-theme name (KDE has
exactly two across light/dark variants — "breeze" / "breeze-dark";
other platforms have one), so the Arc<str> dedup benefit does not apply.
layout: LayoutThemeLayout spacing shared by both variants: the platform reader’s values
merged field-wise over the preset’s, the same precedence the pipeline
uses for colours. None in a field means neither the platform nor the
preset specifies it (platform-facts §2.20); nothing is invented.
accessibility: AccessibilityPreferencesOS-detected accessibility preferences (shared across variants).
Implementations§
Source§impl SystemTheme
impl SystemTheme
Sourcepub fn pick(&self, mode: ColorMode) -> &ResolvedTheme
pub fn pick(&self, mode: ColorMode) -> &ResolvedTheme
Pick a resolved variant by color mode.
§Examples
use native_theme::theme::ColorMode;
let sys = native_theme::SystemTheme::from_system()?;
let dark = sys.pick(ColorMode::Dark);
let active = sys.pick(sys.mode);Sourcepub fn icon_theme_for(&self, mode: ColorMode) -> Option<&str>
pub fn icon_theme_for(&self, mode: ColorMode) -> Option<&str>
The icon-theme name for one colour mode, resolved for that mode’s
variant by the same three tiers as icon_theme
(its defaults.icon_theme, then the theme’s, then the detected system
theme); for the mode the theme was built in it equals icon_theme as
built. KDE names one theme per variant (breeze, breeze-dark); a
toolkit that keeps a style per colour scheme needs both. None where
that variant states none and detection failed; nothing is invented.
Sourcepub fn with_overlay(&self, overlay: &Theme) -> Result<Self>
pub fn with_overlay(&self, overlay: &Theme) -> Result<Self>
Apply an app-level TOML overlay and re-resolve.
Merges the overlay onto the pre-resolve ThemeMode (not the
already-resolved ResolvedTheme) so that changed source fields
propagate correctly through resolve(). For example, changing
defaults.accent_color in the overlay will cause button.primary_background,
checkbox.checked_background, slider.fill, etc. to be re-derived from
the new accent color.
§Examples
let system = native_theme::SystemTheme::from_system()?;
let overlay = native_theme::theme::Theme::from_toml(r##"
[light.defaults]
accent_color = "#ff6600"
[dark.defaults]
accent_color = "#ff6600"
"##)?;
let customized = system.with_overlay(&overlay)?;
// customized.pick(customized.mode).defaults.accent_color is now #ff6600
// and all accent-derived fields are updatedSourcepub fn from_system() -> Result<Self>
pub fn from_system() -> Result<Self>
Load the OS theme synchronously.
Detects the platform and desktop environment, reads the current theme
settings, merges with a platform preset, and returns a fully resolved
SystemTheme with both light and dark variants.
The return value goes through the full pipeline: reader output ->
resolve -> validate -> SystemTheme with both light and dark
ResolvedTheme variants.
§Platform Behavior
- macOS: with the
macosfeature, reads both light and dark variants via NSAppearance and merges them with themacos-sonomapreset. - Linux: Uses
pollster::block_onto drive the async inner implementation, which handles portal D-Bus calls when theportalfeature is enabled. Without a reader for the detected desktop (feature disabled, or a desktop with no reader), returns theadwaitapreset resolved in the detected light/dark mode. - Windows: with the
windowsfeature, reads the active variant and merges it with thewindows-11preset. - Other platforms: Returns
Error::PlatformUnsupported.
§Errors
Error::FeatureDisabledon macOS or Windows when themacos/windowsfeature is not enabled.Error::PlatformUnsupportedif the platform has no reader at all.Error::ReaderFailedif the platform reader cannot access theme data.
§Examples
let sys = native_theme::SystemTheme::from_system()?;
let theme = sys.pick(sys.mode);
// Icon set and theme are on SystemTheme, shared across variants
let _icon_set = sys.icon_set;
let _icon_theme = &sys.icon_theme;Sourcepub async fn from_system_async() -> Result<Self>
pub async fn from_system_async() -> Result<Self>
Async version of from_system().
On Linux, this enables portal D-Bus calls (e.g. GNOME settings portal,
KDE portal backend detection) via .await. On macOS and Windows, the
future completes immediately – no actual async operations occur.
Returns a SystemTheme with both resolved light and dark variants,
same as from_system().