feat(theme): themes as files (theme crate: toml subset + ints, contrast check, wire); whimsy dark + light; display reads themes/, serves THEME/THEME_NAME, init SET_THEME -> THEME_CHANGED to all windows, bar themed; k-ui follows; settings appearance; init keeps choice in sealed users/<id>/settings/, reapplies at sign-in + display restart

This commit is contained in:
2026-10-28 13:36:57 +01:00
parent 29becf297c
commit 6827e1455d
43 changed files with 1140 additions and 179 deletions

View File

@@ -37,9 +37,11 @@ declares `display`. Nothing gets anything "just in case".
apps/<id>/ an app they installed
data/<id>/ an app's private folder (its `storage`, its own key)
permissions/<id> their decisions, one file per app id
settings/ init's record of their choices (the theme)
/bin/ system servers and the shell (init starts these)
/themes/ the themes the display offers (`*.toml`)
/factory/ plaintext starter content a user's folder is
seeded from (home/, permissions/, data/)
seeded from (home/, permissions/, settings/, data/)
```
Users each decide for themselves, even about the system's apps, and what

View File

@@ -186,6 +186,19 @@ opener is remembered: when init sees a program that uses the display go,
it says so (`FORGET`, through its printer thread so it never waits on the
display), and that program's windows close.
The display also holds the theme in use (`theme` crate: tokens, their
TOML files, contrast checks). At start it reads `themes/*.toml` through a
read-only grant, keeps each one that parses and passes contrast (the
built-in Whimsy Dark if none does), and releases the grant (storage has
few connections). Any window can list them (`THEME_NAME`) and read the
one in use (`THEME`, two words a call, `theme::wire`). Only init picks it
(`SET_THEME`, unbadged): then every window, behind or in front, is queued
`THEME_CHANGED` and signalled, and the bar is drawn in it. Init picks the
signed-in user's choice at sign-in, the default at sign-out, and both
again (with `SET_USER`) when the display restarts. A user chooses through
Settings: `types::spawn::SET_THEME` on init's session copy, which init
keeps sealed in `users/<id>/settings/theme`.
Input reaches apps through the display server, the input server's only
client. It subscribes to the input server with a notification, drains it
when signalled, keeps F1, and queues the rest for the window in front,