Architecture

Where the boundary is, what a frame does, and what the language decided rather than the design.

The boundary

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.

the files
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

What a frame is

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.

What the language decided

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.

And what building it found

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.

The language they were fixed in →

What is not here yet

  • multiple OS windows
  • a floating panel torn off a dock into a window of its own
  • text selection across lines
  • right-to-left and complex scripts — the font engine maps codepoints to glyphs one at a time, which is honest for Latin, Greek and Cyrillic and wrong for Arabic and Devanagari
  • CFF  outlines, so an OpenType font with cubic curves loads and reports that it has none
  • saving and restoring a dock arrangement
  • animation beyond a blinking caret
  • images