appearance
Portal appearance settings: colour scheme, accent colour, contrast and reduced motion.
Follow the system’s dark mode and accent colour instead of hardcoding them:
local scheme = mantle.appearance:map(function(appearance)
return appearance.color_scheme or "default"
end, "default")
rect {
padding = 8,
background = scheme:map(function(name)
return name == "light" and "#EFF1F5" or "#1E1E2E"
end),
border = {
width = 2,
color = mantle.appearance:map(function(appearance)
return appearance.accent or "#89B4FA"
end, "#89B4FA"),
},
}
State
mantle.appearance:get() returns AppearanceState, nil before the first push. A field marked ? may be absent.
mantle.appearance’s payload: the org.freedesktop.appearance settings of xdg-desktop-portal.
Without a portal, or for a key it does not provide, a field holds its default; the capability
is never nil after it starts.
| Field | Type | Description |
|---|---|---|
accent? | string | System accent colour as "#rrggbb" (sRGB), or nil when none is set. |
color_scheme | ColorScheme | Preferred colour scheme; "default" means no preference. |
contrast | Contrast | Preferred contrast level. |
reduced_motion | boolean | true when the user asks for reduced motion; false for no preference or an older portal. |
ColorScheme
The user’s preferred colour scheme, from the portal’s color-scheme.
| Value | Description |
|---|---|
"default" | No preference, or a value the portal does not define. |
"dark" | The user prefers a dark appearance. |
"light" | The user prefers a light appearance. |
Contrast
The user’s preferred contrast level, from the portal’s contrast.
| Value | Description |
|---|---|
"normal" | No preference, or a value the portal does not define. |
"high" | The user prefers higher contrast. |
Actions
None: read-only, so any method but get, map and on_change raises.
Backend
| Field | Portal key (org.freedesktop.appearance) | Default |
|---|---|---|
color_scheme | color-scheme: 1 is "dark", 2 is "light" | "default" |
accent | accent-color: an sRGB triple in [0, 1], as "#rrggbb" | nil, also for a triple out of range |
contrast | contrast: 1 is "high" | "normal" |
reduced_motion | reduced-motion: 1 is true | false |
The source is org.freedesktop.portal.Settings on the session bus. Mantle reads the namespace once,
then again on each SettingChanged in it and when org.freedesktop.portal.Desktop gains or loses an
owner. Any other value of a key, or a key the portal does not provide, is the default.
Gotchas
| Trap | Fix |
|---|---|
| Every field stays at its default | No portal backend owns org.freedesktop.portal.Desktop on the session bus. Install xdg-desktop-portal with a backend that serves Settings (GNOME, KDE and xdg-desktop-portal-gtk do) |
reduced_motion is always false | The portal predates the reduced-motion key |