| glimmer-cosmic: a libcosmic backend for glimmer (spike) 6a3304d nandi 8d ago | 1 | # glimmer-cosmic |
| 2 | |
| 3 | The **libcosmic** backend for glimmer — a spike. The same hiccup that |
| 4 | [glimmer-vidya](../glimmer-vidya) paints with egui and [glimmer-tui](../glimmer-tui) |
| 5 | paints in a terminal, painted with COSMIC's widgets and theme through |
| 6 | [`crates/jolt-cosmic`](../../crates/jolt-cosmic). |
| 7 | |
| 8 | ```bash |
| 9 | cargo build --release -p jolt-cosmic |
| 10 | LD_LIBRARY_PATH=../../target/release jolt counter |
| 11 | LD_LIBRARY_PATH=../../target/release jolt smoke # non-interactive, quits itself |
| 12 | ``` |
| 13 | |
| 14 | ## What is the same |
| 15 | |
| 16 | The tree half is glimmer-vidya's. Nodes are integer handles in a Rust arena, |
| 17 | props are written across by name, handlers stay on the jolt side and are found |
| 18 | by node id when an event comes back, and a widget writes its new value into its |
| 19 | own props so a control that ignores its event still works. |
| 20 | |
| 21 | ## What is not: who owns the loop |
| 22 | |
| 23 | egui lets its caller drive frames. libcosmic does not: `cosmic::app::run` takes |
| 24 | the main thread (winit insists) and keeps it until the window closes. So the |
| 25 | loop is inverted: |
| 26 | |
| 27 | ``` |
| 28 | main thread cosmic_run ──────────────────────────────────── returns on close |
| 29 | ▲ wake(tree) │ click / change / toggled |
| 30 | worker (future) mount → commit → wait ─ drain, dispatch, timers → commit → wait … |
| 31 | ``` |
| 32 | |
| 33 | * The reconciler runs on a worker, which is the "UI thread" as glimmer sees it: |
| 34 | `schedule` queues onto it, handlers and timers run on it. |
| 35 | * Its edits land in the arena under a mutex, but libcosmic paints a snapshot |
| 36 | taken at `cosmic_tree_commit`, once per pass. A reconcile half-way through a |
| 37 | patch is never on screen, and a pass that changed nothing commits nothing. |
| 38 | * The worker sleeps in `cosmic_wait` until there is an event, a `schedule`, a |
| 39 | due timer or a close — an idle window costs neither side anything. |
| 40 | * Every call but `cosmic_run` is safe from any thread, which is not true of |
| 41 | libvidya. |
| 42 | |
| 43 | ## Spike limits |
| 44 | |
| 45 | * Tags: `:window` `:box`/`:hbox`/`:vbox` `:page` `:card` `:frame` `:scroll` |
| 46 | `:label` `:title` `:title-2` `:dim-label` `:button` `:checkbutton` `:entry` |
| 47 | `:separator` `:spacer` `:progress`. Anything else paints as a column. |
| 48 | * Events: `click`, `toggled`, `change`, `activate`. |
| 49 | * One window per process — winit cannot make a second event loop — so there is |
| 50 | no REPL `start!`/`stop!` yet, and no headless test beyond the arena's own |
| 51 | Rust tests. |
| 52 | * libcosmic is MPL-2.0 and a git dependency; see `crates/jolt-cosmic/Cargo.toml`. |