Where the boundary is, what a frame does, and what the language decided rather than the design.
The C underneath does four things: open a window, report what the user did, hand over a buffer of pixels, and go to sleep until something happens. It does not draw. The whole C surface is runtime/kv.h — a framebuffer, a byte blob, an event struct, and accessors for each, every hot one static inline and so inlined into Keal.
That is why adding Windows and then Linux changed nothing above runtime/. A backend is one file against a dozen functions.
runtime/ kv.h the whole C surface: framebuffer, blob, event, accessors kv_cocoa.m macOS: NSWindow, a layer-backed view, a ring of events kv_win32.c Windows: the same, through Win32 and GDI kv_x11.c Linux: the same, through Xlib alone src/ ffi.keal the only file in keal-view that mentions C color.keal colour packed in an Int — the per-pixel loop geom.keal rectangles, insets, and the cell-coverage function canvas.keal the rasteriser font.keal TrueType, parsed and rasterised text.keal measuring, wrapping, ellipsising, caret hit-testing theme.keal the palettes, the metrics, and Paint view.keal the tree an application describes layout.keal measuring it and giving every node a rectangle paint.keal every widget's appearance, and icons drawn from strokes ui.keal what outlives a tree rebuilt every frame event.keal what happened, in points state.keal Cell<T> and one revision counter dock.keal splits, tabs, and dragging a panel between them popup.keal menus, dialogs and tooltips app.keal the loop, and how input gets back to the application
Build the tree from the state, lay it out, hand it the events that arrived, and — if a handler changed anything — build and lay it out once more before drawing. Dispatching against a fresh layout rather than the last frame's is what keeps a click landing on what was under the pointer when it happened, even on the frame where the window was resized.
The tree is thrown away and made again. There is no diff, and so nothing to forget to invalidate. What outlives it — hover, focus, scroll offsets, carets — is keyed by identity in ui.keal, and a node's identity is where it is unless it was given a key.
Between frames the loop is inside kvWait, which blocks. An idle window uses no processor at all. That sentence sat in the README for two days before anyone measured it, and when someone did it was false on Windows: with the pointer resting anywhere over the window, the wait returned instantly for ever and the process held 96 % of a core. It is fixed, and the checklist now asks for the measurement twice.
One place where keal-view's shape is chosen by Keal rather than by the design: a trait is not a type in Keal, so a List<Widget> of different implementations cannot exist. One View class with a kind is what the language offers. The constructors and the chained modifiers are the real interface, and nothing outside view.keal sets kind by hand.
This framework was the first real use anything had made of several corners of the compiler, and it found four defects in it — a call whose callee is a field of function type; a local that did not shadow an imported function of the same name; a lambda that could not capture a top-level binding; and Int having no bitwise operators. All four are fixed upstream, and this repository was rewritten to suit.
CFF outlines, so an OpenType font with cubic curves loads and reports that it has none