Apply OS theme via native-theme on desktop

This commit is contained in:
2026-10-21 21:09:00 +07:00
parent 6117c8184c
commit cab58f6332
7 changed files with 413 additions and 31 deletions
+34 -8
View File
@@ -1,10 +1,23 @@
# Migrate the UI to GPUI-Kit, then native-theme
> **Status: Phase A is implemented** (on the working tree, uncommitted). The
> app builds against `gpui-kit` (resolved 0.7.3 / gpui-pre 0.3.9), every UI
> element comes from the kit, and `crates/theme` is deleted.
> **Status: Phase A and Phase B are implemented** (on the working tree,
> uncommitted). The app builds against `gpui-kit` (resolved 0.7.3 /
> gpui-pre 0.3.9), every UI element comes from the kit, and `crates/theme` is
> deleted.
>
> **Follow-up (this revision, also uncommitted):** the last custom modules in
> **Phase B** adopted the OS theme through `native-theme-gpui` 0.6.1 (see
> below). `desktop` reads `SystemTheme::from_system()` at boot — before the
> window opens — and calls `apply_system_theme`, then honors the persisted
> appearance mode on top of it; a `watch`-feature subscription re-applies the
> OS theme at runtime via `native_theme::watch::on_theme_change`. Where the
> OS cannot be read, the boot logs a warning and the kit palette remains.
> The optional preset picker was skipped, matching the signed reference
> (its adoption removed its theme pickers — the connector owns fonts,
> radius and geometry). Web is untouched: `native-theme` is a desktop-only
> dependency and the wasm32 failure set is byte-for-byte the pre-existing
> baseline.
>
> **Follow-up (also on the working tree):** the last custom modules in
> `crates/ui` are gone — `motion`, `typography`, `layout` and `styled` were
> deleted and every call site now reads gpui-kit tokens directly (`text_xs` /
> `text_sm`, `cx.theme().radius` / `radius_lg`, `gap_2`, `Separator`). The
@@ -15,10 +28,9 @@
> (`ui::Avatar`): user image when set, deterministic pixel art from the
> profile/group seed otherwise, also as the image-load fallback. Desktop
> traffic lights recenter for the 44px bar (`workspace::TAB_BAR_HEIGHT`).
> Validation: `cargo check`, `cargo clippy` and `cargo fmt` are clean
> workspace-wide and the desktop binary builds; the wasm32 check fails
> identically before and after (pre-existing `state` → `gpui_tokio` and
> `rustls` blockers, verified at HEAD).
> Icons are vendored in `assets/icons/` (signed's set, filled from the kit
> bundle where coop needs more) and regression-tested in
> `crates/assets/tests`.
Plan to move coop's custom UI elements onto [GPUI-Kit](https://gpui-kit.com)
(`gpui-kit` 0.7.1), delete the custom theme implementation (`crates/theme`),
@@ -257,6 +269,20 @@ site is mapped.
## 5. Phase B — native-theme-gpui
> **Implemented.** `native-theme` 0.6.1 (`watch`) + `native-theme-gpui` 0.6.1
> (default-features off, `system-fonts`) are workspace deps; only `desktop`
> depends on them, so nothing enters the wasm graph. `desktop/src/main.rs`
> applies the OS theme after `settings::init` and before the window opens,
> then honors the persisted appearance mode; on read failure it logs a
> warning and keeps the kit palette (which the appearance dropdown still
> drives). A `ThemeWatcher` global holds the `watch` subscription and
> re-applies on OS theme changes through a flume channel. The optional
> preset picker (step 3) was skipped, matching the signed reference where
> adoption *removed* the theme pickers. Settings, workspace and all UI
> crates are untouched — Phase A's appearance controls work on the native
> palettes as planned. The web fallback-preset idea was dropped with it:
> web keeps the kit palette and its appearance dropdown, exactly as before.
1. Add `native-theme-gpui = "0.6"` (pulls `native-theme`; keep default
features or trim icon features coop doesn't use).
2. Boot, after `gpui_kit::init` and before opening the window: