Expand description
Authoring guide: the two public tiers of the UI API.
§Authoring GPUI
UI is written at one of two levels: composing the built-in elements into components, or writing a custom element when nothing built in emits what you need. Both levels are public, so code written against them today should keep compiling across minor releases.
§Composing components
Most UI is built from div() and the other element
constructors, refined with style and interaction builders:
Styledfor layout and appearance:.p_4(),.bg(),.w_full(), and the rest of the utility-style methods.InteractiveElementfor listeners:.on_click(),.on_mouse_down(),.on_key_down().RenderandRenderOnceto turn your own types into elements.EntityandContextfor the state that drives them.
This level composes; it does not draw. Painting is decided by the elements being composed.
§Writing custom elements
When nothing built in draws what you need, implement
Element. Its lifecycle runs in three phases:
Element::request_layoutasks the layout engine for aLayoutId, throughWindow::request_layoutor, for leaf content whose size only its own measurements know,Window::request_measured_layout.Element::prepaintruns once the element’sBoundsare known. This is where you register hitboxes withWindow::insert_hitboxand stash whatever state painting will need.Element::paintemits the drawing:Window::paint_quaddraws aPaintQuad, the same primitive adiv()uses for its background, border and corner radii.Window::paint_pathdraws arbitrary vector geometry, built withPathBuilderinto an engine-levelPath.Window::paint_drop_shadowsandWindow::paint_inset_shadowsdrawBoxShadows, before and after the element’s fill respectively.Window::paint_imagedraws an image.Window::layout_boundsreads a child’s computed bounds.
None of these name a GPU API or an operating system. Each call appends a
record to the frame’s scene, and the engine’s
SceneRenderer turns those records into whatever the
backend draws, so a custom element keeps working when the renderer is
replaced. LayoutId is likewise an opaque token, so a
custom element keeps working when the layout engine is replaced.
Compositing pixels produced outside GPUI is the one place a platform-specific
payload reaches the window. It goes through gpu_canvas,
whose callback receives a GpuCanvasContext: the
context’s paint_surface takes a CoreVideo buffer, a Direct3D texture or
view, or a dma-buf, and its paint_texture takes a texture made on the
window renderer’s own device.
§What is not authoring API
Part of Window’s public surface exists for the runtime and
for test harnesses rather than for elements:
- Frame orchestration:
compute_layout,present_if_needed, damage diffing anddraw.drawstays public because the visual test harnesses render frames with it, and is hidden from these docs. - Element storage: the erased
ElementObject, the element arena, and the stack-safety wrapper around it. - Frame double-buffering and the retained hit-test tree.
- The inspector: the runtime publishes the identity of the element it is laying out or painting, so elements never handle it themselves.
Depend on the authoring surface instead. If something in that list is the only way to express what you need, that is a gap worth reporting.
§The rest of Window is runtime API
The remaining methods on Window are public on purpose, and
they are not authoring API: window management, input, focus, event
subscriptions, element state and assets. Whether a component or an
element needs them is a judgement each call site makes, so they are neither
hidden here nor treated as a frozen contract.