update plan
This commit is contained in:
+44
-18
@@ -1,6 +1,6 @@
|
||||
# gpui-native-kit — Project Plan
|
||||
|
||||
Rev 6 (2026-10-28). Changes from rev 5: components are built **one element at a time behind a review gate** — each unit is designed, implemented, tested, shown in the gallery, and reviewed before the next starts (batch waves are gone). [gpui-kit `base`](https://github.com/longbridge/gpui-kit/tree/main/crates/base) is re-admitted as the **API-design reference**: its unstyled-control conventions (controlled state, one activation path for pointer + Enter + Space, semantic states, a11y labels) shape our component APIs, and small utilities may be adapted where they help. Everything else (empty-project reset, theme engine as the product, crate split, per-component features) stands.
|
||||
Rev 7 (2026-11-01). Changes from rev 6: units 1–14 plus the data crate are landed and marked (§6, §12); per-platform elevation stacks landed (D24); §6.3 adds the migration-driven roadmap for [signed](https://git.reya.info/reya/signed) — the first downstream app — after fresh bezel and gpuikit component surveys; the migration itself is Phase H (§7). The rev 6 rules stand: components are built **one element at a time behind a review gate** — each unit is designed, implemented, tested, shown in the gallery, and reviewed before the next starts (batch waves are gone). [gpui-kit `base`](https://github.com/longbridge/gpui-kit/tree/main/crates/base) is re-admitted as the **API-design reference**: its unstyled-control conventions (controlled state, one activation path for pointer + Enter + Space, semantic states, a11y labels) shape our component APIs, and small utilities may be adapted where they help. Everything else (empty-project reset, theme engine as the product, crate split, per-component features) stands.
|
||||
|
||||
## 1. Vision
|
||||
|
||||
@@ -51,7 +51,7 @@ gpui-native-kit/ # repo root = workspace root
|
||||
│ ├── core/ # gpui-native-core: components every app needs
|
||||
│ │ # (one cargo feature per component)
|
||||
│ ├── data/ # gpui-native-data: List, Tree, Tabs, Sidebar (one cargo feature each)
|
||||
│ └── editor/ # gpui-native-editor: created when wave 2 needs it (D12)
|
||||
│ └── editor/ # gpui-native-editor: created when the editor units need it (D12, §6.3 M15)
|
||||
└── examples/
|
||||
└── gallery/ # showcase; a page per component + theme/icon inspector
|
||||
```
|
||||
@@ -72,7 +72,7 @@ One-way, no cycles. Nothing depends on `gpui-component`, `gpui-kit`, `gpuikit`,
|
||||
|
||||
### 4.2 Feature model
|
||||
|
||||
- **One feature per component** in `core` (`button`, `checkbox`, `switch`, `radio`, `toggle`, `link`, `slider`, `progress`, `avatar`, `input`, `popover`, `tooltip`, `menu`, `dialog`, `toast`, `list`, `tabs`, …). `default = ["full"]`; lean apps use `default-features = false` + the features they want.
|
||||
- **One feature per component** in `core` (`button`, `checkbox`, `switch`, `radio`, `toggle`, `link`, `slider`, `progress`, `avatar`, `input`, `popover`, `tooltip`, `menu`, `dialog`, `alert`, `toast`, …) and in `data` (`list`, `tree`, `tabs`, `sidebar`). `default = ["full"]`; lean apps use `default-features = false` + the features they want.
|
||||
- Features **gate whole modules only** (`#[cfg(feature = "…")] pub mod button;`) and are additive. A component that composes another declares the dependency in Cargo.toml (`dialog = ["button"]`). No cfg logic may cross modules.
|
||||
- Facade features map to crates: `core` (default), `editor`, `data`, …
|
||||
- Shared helpers promoted per D16 live in an ungated `common` module so every feature combination sees them.
|
||||
@@ -158,7 +158,7 @@ The set stays role-minimal and grows one concept at a time, driven by the unit t
|
||||
- ~~**Scrollbar thumb token + metrics**~~ — ✅ landed with the ScrollArea unit (2026-10-29): `colors.scrollbar_thumb` (translucent over content: black in light, light gray in dark; TOML-overridable) and `Theme.scrollbar` (`width` 8 pt, `inset` 2 pt, `min_thumb` 24 pt).
|
||||
- ~~**`success` / `warning` roles**~~ — ✅ landed with Toast (2026-10-29): `colors.success`/`warning` (+ foregrounds; light and dark variants; TOML-overridable; no platform states them) and derived `Ramps.success`/`warning` via the OKLCH engine, matching the destructive treatment. **`info` joined them (2026-10-31)** — the fourth severity, same treatment (`colors.info` + foreground + `Ramps.info`, neutral sky blue, no platform states it, TOML `info =`). Trigger: the Alert's Info severity was painting from the primary ramp, so a warm platform accent (GNOME red, Omarchy red themes) made Info read as Danger; the token keeps Info calm however the accent turns out. Severity tokens now use the same picked value for the ramp and the token (the success/warning tokens used to re-pick with the system slot dropped, diverging from their own ramps if a platform ever stated one).
|
||||
- **Motion tokens** — after the reverted framework attempt (2026-10-30), motion stays minimal: `Motion.overlay` (200 ms) is the only token. Components reach for gpui's own easings and `SpringConfig` inline (D21); a token is added only when a third component shares the same value (D16). TOML `[motion]` overrides and per-platform motion presets wait for a real need. ~~The reduce-motion forwarding fix~~ ✅ landed (pass a, 2026-10-30): `reapply` calls `cx.set_reduce_motion(resolved.accessibility.reduce_motion)`, so gpui's animation elements snap under the OS setting.
|
||||
- **`knob` / control-fill role** — only if Slider (unit 7) confirms the Switch's borrowed roles (`primary_foreground` thumb, `border` off-track) as a second consumer; until then no expansion.
|
||||
- ~~**`knob` / control-fill role**~~ — resolved without a token: Slider (unit 7) shipped on the Switch's borrowed roles (`primary_foreground` fill, `border` off-track); a dedicated role waits for a third consumer.
|
||||
|
||||
Controls through unit 10 paint from existing roles and ramps.
|
||||
|
||||
@@ -202,7 +202,7 @@ Real semantic colors per platform (`NSColor` / `UISettings` / portal) instead of
|
||||
|
||||
## 6. Component roadmap (review units, in order)
|
||||
|
||||
Each row is one review unit: build it, show it in the gallery, review, then move on.
|
||||
Each row is one review unit: build it, show it in the gallery, review, then move on. Units 1–10 ✅ landed (2026-10-29) — Button through Input (§6.2); the rows keep their original scope notes. Rows 11 onward carry their status inline.
|
||||
|
||||
| Unit | Crate | Component | Notes |
|
||||
| --- | --- | --- | --- |
|
||||
@@ -225,7 +225,7 @@ Each row is one review unit: build it, show it in the gallery, review, then move
|
||||
| then | pickers or data | Calendar/DatePicker, TimeField, ColorPicker | Decide at unit time. |
|
||||
| editor | editor (new) | Text/code editor, syntax highlighting (D12) | Same gate. |
|
||||
|
||||
Deferred until a real need: Markdown/TextView, Dock, VirtualList, window-wide text selection, overlay exit animations and hover washes (dropped with the 2026-10-30 revert; only return if a genuinely simple approach appears), charts.
|
||||
Deferred until a real need: Dock (signed ships its own), window-wide text selection, overlay exit animations and hover washes (dropped with the 2026-10-30 revert; only return if a genuinely simple approach appears), charts. Markdown/TextView and VirtualList gained consumers through the signed migration — promoted to §6.3 (M14, M17).
|
||||
|
||||
### 6.1 After the core units: sizing API — ✅ landed
|
||||
|
||||
@@ -250,20 +250,44 @@ Remaining, in order:
|
||||
| 5 | Caret blink | ✅ Landed. A private `CaretBlink` entity per `InputState`: 500 ms tick on the GPUI executor, visible on focus and hidden after one interval. Any field change (`InputState::notify`) pauses it — caret solid, cycle restarts — so typing, moving and dragging never hide it; generation counters invalidate stale ticks. Read-only suppresses the caret entirely. `caret_visible(focused, cx)` is the single gate used by paint and tests |
|
||||
| 6 | Paint polish | ✅ Landed. IME composition underline (1 px, foreground token) under the marked range. I-beam hover cursor via a canvas-prepaint hitbox + `set_cursor_style` in paint. Two-sided horizontal scroll: `scroll_offset` lives in state; caret-affecting changes set a pending flag that the next paint consumes with a fresh layout (two-sided pull-back + clamp to content), while `scroll_by` (wheel, `ScrollEvent`, lines→pixels via a fixed unit) bypasses the flag so manual pans survive. Scroll-aware hit-testing, IME `bounds_for_range` and drag select all come free through the scroll-adjusted origin |
|
||||
|
||||
Deferred until a real need: bidi/RTL; prefix/suffix adornments and a form field wrapper (label/description/error — separate units); `SubmitOn` enter/cmd-enter modes (multiline concern); `Undo`/`Redo` events; selection/cursor color overrides (theme tokens are deliberate); password masking, max length, clear button (gpuikit has none of these either — decide on first need).
|
||||
Deferred until a real need: bidi/RTL; prefix/suffix adornments; `SubmitOn` enter/cmd-enter modes (multiline concern); `Undo`/`Redo` events; selection/cursor color overrides (theme tokens are deliberate); max length, clear button (gpuikit has none of these either — decide on first need). Password masking and the form field wrapper lifted 2026-11-01 — §6.3 M6/M9.
|
||||
|
||||
### 6.3 Migration-driven additions — signed is the first downstream app
|
||||
|
||||
The first real consumer is [signed](https://git.reya.info/reya/signed), a Nostr Git platform desktop client (GPL-3.0, v0.2.0) currently built on `gpui-pre` 0.3.8 + gpui-component 0.7.1 + native-theme 0.6.1. Migrating it means the zed-pinned gpui under D3, `gpui-native-theme` in place of native-theme(-gpui), and our components replacing gpui-component view by view; `signed_ui`, `workspace`, and its dock stay app-side (dock stays off the roadmap — the app owns it). Its screens drive the units below. A survey of bezel's full catalog (bezel.gallery docs, 2026-11-01) and gpuikit's showcase source shaped the shapes, not the scope — API ideas only per D15.
|
||||
|
||||
Wave M1 — unblocks the port; each through the review gate:
|
||||
|
||||
| Unit | Crate | Component | Signed consumer | Survey notes |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| M1 | core | Badge | unsynced-count pills on sidebar repo rows | bezel ships quiet + active variants; gpuikit secondary/outline/destructive. D22's deferred consumer arrives — token needs decided at review |
|
||||
| M2 | core | Select | default-branch chooser, event-fetch-strategy setting, explore filter | bezel: field-shaped trigger over a caller-assembled menu; gpuikit: placeholder + clear. Composes our Popover + Menu — no new overlay machinery |
|
||||
| M3 | core | Segmented control | All/Popular/Recent explore filters | bezel's toggle-group pill; single-select first, multiple waits |
|
||||
| M4 | core | Context menu | repo rows, file-tree rows, tab bar | gpuikit attaches the menu to an existing element; bezel keys one-open-at-a-time. Reuses the Menu panel |
|
||||
| M5 | core | Empty state | inbox, issues, search misses | bezel: icon + headline + hint + optional action. Trivial paint over tokens |
|
||||
| M6 | input | Password input | identity unlock + `nsec` import passphrase | lifts §6.2's "password masking on first need" — the need arrived |
|
||||
| M7 | input | Multiline textarea | discussion composer, patch + commit messages | bezel: fixed rows or min/max auto-grow; gpuikit: rows on InputState. Reuses Input's buffer; D12's editor crate stays separate |
|
||||
| M8 | core | Avatar image | profile pictures in rows and panel tabs | lifts the deferred image slot: gpui `img` + initials fallback (signed adds its pixel-art fallback app-side) |
|
||||
|
||||
Wave M2 — completes the surface: Field wrapper (M9: label/description/error around any control — the settings dialog; lifts another §6.2 deferral), Tag (M10: removable GRASP-server and relay entries), Status dot (M11: sync-drift beads on rows), Combobox (M12: type-to-filter pickers; gpuikit's `on_create`/`keep_unmatched` blur modes are worth copying), Command palette (M13: filtered actions — gpuikit keeps the matcher caller-owned, adopt that), VirtualList in `data` (M14: a thin `uniform_list` binding for commit histories and the inbox).
|
||||
|
||||
Wave M3 — content, where `crates/editor` starts (D12): code view with syntax highlighting (M15 — signed renders highlighted files with tree-sitter today), then the color-coded diff view (M16), then a Markdown view (M17) if the port confirms READMEs and issue bodies need one.
|
||||
|
||||
Survey notes — worth adopting later, not now: bezel's hover card (profile previews), skeleton rows, breadcrumb, pagination, sortable lists, follow-scroll; gpuikit's table (stays dropped — signed's explore lists read fine as Sidebar rows), kbd chips (our Menu already renders shortcut hints), form fieldset (the Field wrapper covers it), accordion.
|
||||
|
||||
## 7. Milestones
|
||||
|
||||
| Phase | Scope | Acceptance |
|
||||
| --- | --- | --- |
|
||||
| A — scaffold (next) | Workspace per §4.1: theme stub, icons crate (`IconRole` + Lucide fallback), core crate with feature scaffolding (zero components), facade, gallery shell, CI incl. feature checks | `gallery` opens a window reading the theme global; `core` builds at default / no-default / all / each-feature-alone |
|
||||
| B — theme engine core | Token model + resolve + presets (neutral fallback, tokyo-night) + macOS source + `ThemeWatcher`; gallery theme inspector. Done: `resolve` overlay chain (base → system → preset → mode override → high-contrast) is pure and tested; OKLCH accent-ramp engine; `NSColor`/`NSWorkspace` adapter; distributed-notification watchers; inspector with live mode/preset switching. (The "Button + Checkbox painted from live tokens" proof moves to Phase C — those components land there; the gallery inspector proves the live pipeline meanwhile.) |
|
||||
| C — controls | One review unit at a time (§6, units 1–9), each: API per §4.3 + tests + gallery page → review gate. macOS SF Symbols resolver behind the icon seam lands with the first unit that shows it matters | Per unit: activation, controlled round-trip, and disabled inertness tested; gallery page shows the live control against the theme; your approval closes the unit |
|
||||
| D — input | Wave 2 | Single-line input with cursor, selection, clipboard; NumberInput |
|
||||
| E — overlays | Wave 3 | Focus trapping and escape/dismiss semantics per overlay |
|
||||
| A — scaffold ✅ | Workspace per §4.1: theme stub, icons crate (`IconRole` + Lucide fallback), core crate with feature scaffolding (zero components), facade, gallery shell, CI incl. feature checks | `gallery` opens a window reading the theme global; `core` builds at default / no-default / all / each-feature-alone |
|
||||
| B — theme engine core ✅ | Token model + resolve + presets (neutral fallback, tokyo-night) + macOS source + `ThemeWatcher`; gallery theme inspector. Done: `resolve` overlay chain (base → system → preset → mode override → high-contrast) is pure and tested; OKLCH accent-ramp engine; `NSColor`/`NSWorkspace` adapter; distributed-notification watchers; inspector with live mode/preset switching. (The "Button + Checkbox painted from live tokens" proof moved to Phase C — those components landed there; the gallery inspector proves the live pipeline meanwhile.) | ✅ Landed (§12 item 2) |
|
||||
| C — controls ✅ | One review unit at a time (§6, units 1–9), each: API per §4.3 + tests + gallery page → review gate. macOS SF Symbols resolver behind the icon seam lands with the first unit that shows it matters | Per unit: activation, controlled round-trip, and disabled inertness tested; gallery page shows the live control against the theme; your approval closes the unit |
|
||||
| D — input ✅ | Single-line Input (unit 10) + the §6.2 completion pass; NumberInput stays deferred (multiline is §6.3 M7) | Modifiers, undo/redo, read-only, actions + key context, caret blink, paint polish all landed |
|
||||
| E — overlays ✅ | Popover (11), ScrollArea (11.5), Menu (12), Tooltip + Dialog/AlertDialog + Toast/Alert (11+ row) | Escape/dismiss semantics and focus behavior verified per overlay |
|
||||
| E+ — motion | Unit 14 (§6): per-component passes, each a few lines on gpui's own primitives — forwarding, Switch thumb, Toast slide, Dialog scrim, Progress cap | ✅ Landed (2026-10-30), each pass reviewed in the gallery; reduce-motion snaps gpui-side with the flag forwarded |
|
||||
| F — platforms + data | `crates/data` + Windows/GNOME/KDE/Omarchy theme sources + Segoe Fluent/freedesktop icon resolvers | Side-by-side gallery screenshots per platform |
|
||||
| G — pickers + polish | Wave 5 → 0.1; start `crates/editor` if wanted | — |
|
||||
| F — platforms + data | ✅ Landed (2026-10-30): `crates/data` (List, Tree, Tabs, Sidebar), the Linux theme sources (Omarchy/KDE/GNOME), the Windows source, the Segoe Fluent + freedesktop icon resolvers, plus per-platform elevation stacks (D24, 2026-11-01) | Remaining acceptance: side-by-side gallery screenshots — a Linux run (Omarchy/KDE/GNOME) and the first Windows hardware build |
|
||||
| G — migration additions (§6.3) | Waves M1–M2: Badge, Select, Segmented, Context menu, Empty state, password + multiline input, Avatar image, then M9+ in signed's port order → 0.1 | Each unit through the review gate; each wave unblocks a real signed screen |
|
||||
| H — signed migration | Port [signed](https://git.reya.info/reya/signed) to `gpui-native-kit`: the zed-pinned gpui replaces gpui-pre 0.3.8, `gpui-native-theme` replaces native-theme(-gpui) 0.6.1, our components replace gpui-component 0.7.1 view by view behind `signed_ui` | One screen per pass, reviewed side by side against the gpui-component build; no regressions in identity, explore, repository, sync, or settings flows |
|
||||
|
||||
Gate for every phase: `cargo fmt --check`, `cargo clippy --workspace --all-targets -- -D warnings`, `cargo test`, gallery smoke run.
|
||||
|
||||
@@ -289,6 +313,7 @@ Pure tests for resolve/overlay chain, payload parsing (fixtures), icon resolutio
|
||||
| Per-component features multiply configurations | Features gate whole modules, additive only; CI checks default / none / all / each-alone, not the full matrix |
|
||||
| Platform icon lookups vary (missing fonts, themes) | Resolver cascade always ends in the bundled Lucide fallback; missing glyph logs once and falls back |
|
||||
| Per-OS readers are a maintenance burden | Thin readers over parseable payloads + fixture tests; graceful fallback chain (system → preset → fallback theme) |
|
||||
| The signed migration crosses gpui distributions (gpui-pre 0.3.8 → zed pinned rev) | Port incrementally behind the `signed_ui` seam; a kit-side unit lands before its screen ports (§7 Phase G → H); the gallery doubles as the API-parity reference |
|
||||
| "Native feel" is judgment | Named native reference per component; per-platform screenshot review each phase |
|
||||
| Omarchy `colors.toml` key set evolves | Parse tolerantly (unknown keys ignored, missing keys fall back); track the theme-set script each release cycle |
|
||||
| Portal `accent-color` absent on older desktops | Treat as unset (spec-defined); fall back to gsettings/KDE accent, then ramp from a neutral accent |
|
||||
@@ -304,7 +329,7 @@ Pure tests for resolve/overlay chain, payload parsing (fixtures), icon resolutio
|
||||
| D7 | `gpui-native-kit` stays the thin facade package name; it only re-exports crates behind features. Applications may depend on `gpui-native-core` directly |
|
||||
| D8 | macOS first, then Windows 11 (WinUI), then GNOME → KDE → Omarchy; fallback theme from day one |
|
||||
| D11 | Bundled presets: neutral `fallback`, `tokyo-night`, per-platform presets for testing readers; Omarchy files load as presets too |
|
||||
| D12 | Editor deferred; `crates/editor` is created when wave 2's multiline editing or highlighting demands it |
|
||||
| D12 | Editor deferred; `crates/editor` is created when the editor units start — the signed migration's file viewing is the trigger (§6.3 M15–M17) |
|
||||
| D13 | Accent shades hybrid: stated platform ramps where available (WinUI, KDE), OKLCH derivation elsewhere |
|
||||
| D14 | Custom-theme live reload via `notify` |
|
||||
| D15 | No wholesale porting, no UI-toolkit dependencies. Component APIs follow bezel and gpuikit conventions where they fit (D20), always simplified — never mirrored 1:1; small utilities may be adapted with attribution |
|
||||
@@ -325,10 +350,11 @@ Dropped from rev 3: D2, D5, D9 (port-era decisions); the review gate returns in
|
||||
1. ~~Phase A scaffold~~ ✅ — workspace, toolchain pin, CI, theme seed, icons crate, core feature scaffolding, facade, gallery shell.
|
||||
2. ~~Phase B theme engine core~~ ✅ — resolve pipeline, OKLCH ramps, presets, macOS source + watchers, gallery theme inspector.
|
||||
3. ~~Phase C controls~~ ✅ — units 1–9 (Button → Avatar), each through the review gate; sizing API (§6.1).
|
||||
4. ~~Phase D input~~ ✅ — single-line Input (unit 10) + the §6.2 completion pass (modifiers, undo/redo, read-only, actions + key context, caret blink, paint polish). NumberInput and multiline remain open as deferred units.
|
||||
4. ~~Phase D input~~ ✅ — single-line Input (unit 10) + the §6.2 completion pass (modifiers, undo/redo, read-only, actions + key context, caret blink, paint polish). NumberInput stays deferred; multiline returns as §6.3 M7.
|
||||
5. ~~Phase E overlays~~ ✅ — Popover (unit 11), ScrollArea (unit 11.5), Menu (unit 12), Tooltip + Dialog/AlertDialog + Toast (unit 11+ row; Sheet dropped). Phase gate held: escape/dismiss semantics and focus behavior per overlay.
|
||||
6. ~~Unit 14 — motion, per component (§6 row 14, D21)~~ ✅ Landed in five passes (2026-10-30): (a) theme `reduce_motion` → `cx.set_reduce_motion` in `reapply`; (b) Switch thumb `with_spring`; (c) Toast 8 px slide-in; (d) Dialog scrim enters with the panel; (e) Progress 30 fps cap. Exits and hover washes stay deferred (§6 deferred list).
|
||||
7. ~~Phase F, data first~~ ✅ data complete (2026-10-30) — `crates/data` opened with List, then Tree, Tabs, Sidebar (the dead `sheet` feature dropped from core along the way; Table dropped from the roadmap). Also extracted `crates/utils` (2026-10-30): `h_flex`/`v_flex` (core's `common` re-exports them), `focus_handle` (the namespaced keyed handle, 8 call sites), `focus_ring` (7 sites), `adjacent_selectable` + `nav_key` (4 sites), and the selectable-row paint helpers `selectable_label_color`/`paint_selectable_row` (3 sites, reading `&Theme` directly — no intermediate color struct) — `core` and `data` depend on it; the facade doesn't re-export it. **Linux theme sources landed (2026-10-30)**: Omarchy (colors.toml parse + state-dir detection + inotify on `current`), KDE (kdeglobals `[Colors:*]` + AccentColor + `~/.config` inotify), GNOME/generic (portal `ReadAll` + `SettingChanged` via zbus 5 blocking on its own thread, gsettings fallback with the libadwaita accent table) — `SourceKind::Omarchy/Kde/Gnome`, detection cascade Omarchy → KDE → portal → fallback, all parsers fixture-tested on every OS and the Linux build compile-checked via `cargo check --target x86_64-unknown-linux-gnu`. **Windows source + icon resolvers landed (2026-10-30)**: `SourceKind::Windows` (WinRT `UISettings` + `Personalize` fallback + `ColorValuesChanged`/`HighContrastChanged`, §5.3), the Segoe Fluent codepoint renderer, and the freedesktop theme walker (§4.4); the WinRT surface was verified against the real `windows` 0.62 bindings via a standalone cross-check (gpui's own manifest build needs llvm-rc from macOS). Remaining Phase F: **side-by-side gallery screenshots per platform** — Omarchy/KDE/GNOME need a Linux run, Windows needs its first hardware build. NumberInput/multiline return as deferred units when needed.
|
||||
8. Then — Phase G: pickers, polish, → 0.1; start `crates/editor` if wanted.
|
||||
7. ~~Phase F, data first~~ ✅ data complete (2026-10-30) — `crates/data` opened with List, then Tree, Tabs, Sidebar (the dead `sheet` feature dropped from core along the way; Table dropped from the roadmap). Also extracted `crates/utils` (2026-10-30): `h_flex`/`v_flex` (core's `common` re-exports them), `focus_handle` (the namespaced keyed handle, 8 call sites), `focus_ring` (7 sites), `adjacent_selectable` + `nav_key` (4 sites), and the selectable-row paint helpers `selectable_label_color`/`paint_selectable_row` (3 sites, reading `&Theme` directly — no intermediate color struct) — `core` and `data` depend on it; the facade doesn't re-export it. **Linux theme sources landed (2026-10-30)**: Omarchy (colors.toml parse + state-dir detection + inotify on `current`), KDE (kdeglobals `[Colors:*]` + AccentColor + `~/.config` inotify), GNOME/generic (portal `ReadAll` + `SettingChanged` via zbus 5 blocking on its own thread, gsettings fallback with the libadwaita accent table) — `SourceKind::Omarchy/Kde/Gnome`, detection cascade Omarchy → KDE → portal → fallback, all parsers fixture-tested on every OS and the Linux build compile-checked via `cargo check --target x86_64-unknown-linux-gnu`. **Windows source + icon resolvers landed (2026-10-30)**: `SourceKind::Windows` (WinRT `UISettings` + `Personalize` fallback + `ColorValuesChanged`/`HighContrastChanged`, §5.3), the Segoe Fluent codepoint renderer, and the freedesktop theme walker (§4.4); the WinRT surface was verified against the real `windows` 0.62 bindings via a standalone cross-check (gpui's own manifest build needs llvm-rc from macOS). Remaining Phase F: **side-by-side gallery screenshots per platform** — Omarchy/KDE/GNOME need a Linux run, Windows needs its first hardware build. NumberInput stays deferred until needed; multiline is §6.3 M7.
|
||||
8. Then — Phase G is the migration additions (§6.3): Badge, Select, Segmented control, Context menu, Empty state, password input, multiline Textarea, Avatar image first — each unblocks a concrete signed screen. Pickers (Calendar/DatePicker, TimeField, ColorPicker) stay decided-at-unit-time. `crates/editor` starts when the port reaches file viewing (M15).
|
||||
9. Then — Phase H, the signed migration itself (§7): theme swap first (native-theme → `gpui-native-theme`), then views one at a time, keeping the gpui-component build side by side until parity.
|
||||
|
||||
Batched polish candidates between units: scrollbar auto-hide + horizontal thumb, `Undo`/`Redo` menu events.
|
||||
|
||||
Reference in New Issue
Block a user