← Otto User GuideOtto Developer Guide

Otto is a Wayland compositor built on Smithay, rendered with Skia, and driven by a retained scene graph (lay-rs).

If you have written a compositor before, the one structural surprise is that Otto does not draw windows imperatively each frame. It maintains a scene graph — a tree of layers with positions, opacity, blur and animations — and hands the whole tree to the renderer as a single render element. Most of src/workspaces/ is code that mutates that tree; almost none of it draws.

Read these first

PageWhat it covers
Project StructureWhere everything lives, feature flags, how to build
RenderingScene graph → render elements → Skia → screen
Render LoopWhen Otto wakes up, when it renders, damage tracking
Wayland ProtocolsThe one-big-state pattern and how to find any protocol handler
The Scene GraphThe layer tree: how it is shaped, how surfaces enter it, how subtrees become KMS planes
LayersThe unit the tree is made of: properties, content closures, transactions, caching, damage

Otto architecture

Subsystems

PageWhat it covers
otto-kitThe toolkit the apps and the compositor’s own chrome are built on
DockThe compositor-drawn dock: data flow, layers, magnification
ExposéThe all-windows overview: layout, mirrors, drag-and-drop, multi-output
Window MoveHow interactive window drags are implemented
DRM PlanesHanding parts of the scene to display hardware instead of the GPU
Foreign ToplevelExposing the window list to taskbars and launchers
Screen SharingPortal, PipeWire, wlr-screencopy, window capture
AccessibilityKey grabs for screen readers, and the shell and kit apps on AT-SPI
Color SchemeHow apps learn whether Otto is in light or dark mode
Settings D-Bus APIThe org.otto.Settings wire contract
RDP BridgeServing a virtual output over RDP (otto-rdp)
Debug Action HookDriving builtin shortcut actions from a script ($OTTO_ACTION_FILE)
Versioning & ReleasesOne workspace version for the compositor and every component, and how to bump it
Remote-Desktop IndicatorThe sharing indicator otto-rdp publishes while a client is watching

Design docs and plans

These describe work that is exploratory, partial, or superseded. Each says so at the top — check that before trusting the details.

PageStatus
otto-kit RoadmapPartially built — gap analysis for the UI toolkit
Surface Style ProtocolSuperseded — the original design behind otto-surface-style-v1
Screenshot Portal PlanPartly built — the portal exists and shells out to grim; Otto-drawn selection is still the plan
AirPlay ScreenshareExploration only

Specs

docs/developer/ explains how things work today. specs/ holds the behavioural contracts — what a feature must do, written to be verified against. Where a subsystem has both, the spec is authoritative for behaviour and the doc is authoritative for structure. See specs/README.md.

Conventions

Two coordinate spaces, and mixing them causes scale-dependent bugs.

Always take the scale from the output itself — output.current_scale().fractional_scale() as f32. WorkspacesModel.scale is a global fallback and does not belong in geometry code.

Suffix physical-pixel variables with _px (width_px, offset_px) so the space is visible at the call site.