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

@@ -1,6 +1,7 @@
//! The encrypted areas (see the vision's Encryption and Users notes), over
//! any file system. Each user's folder `users/<id>/` holds their areas:
//! `home/`, `permissions/`, and per app `apps/<app>/` and `data/<app>/`,
//! `home/`, `permissions/`, `settings/` (init's record of their choices,
//! such as the theme), and per app `apps/<app>/` and `data/<app>/`,
//! each kept as `filecrypt` files under its own key, derived from that
//! user's master key. Only the signed-in user's areas open; anyone else's
//! are refused (and noise to their key anyway). The rest (programs,
@@ -42,7 +43,7 @@ fn area(path: &[u8]) -> (Area<'_>, Option<&[u8]>) {
let upto = |n: usize| &path[..n];
let base = 6 + user.len() + 1;
let area = match (kind, app, rest) {
(Some(k @ (b"home" | b"permissions")), _, _) => Area::Sealed(upto(base + k.len())),
(Some(k @ (b"home" | b"permissions" | b"settings")), _, _) => Area::Sealed(upto(base + k.len())),
(Some(k @ (b"apps" | b"data")), Some(a), Some(r)) if !a.is_empty() && !r.is_empty() => Area::Sealed(upto(base + k.len() + 1 + a.len())),
_ => Area::Neither,
};

View File

@@ -154,6 +154,7 @@ fn areas_are_told_by_path() {
(&b"users/u1/home/readme.txt"[..], "sealed"),
(b"/users/u1/home", "sealed"),
(b"users/u1/permissions/kos.snake", "sealed"),
(b"users/u1/settings/theme", "sealed"),
(b"users/u1/data/kos.notes/a", "sealed"),
(b"users/u1/apps/kos.notes/notes", "sealed"),
(b"users/u1/data/kos.notes", "neither"),