# ADR 0004 — Overlapping-window GUI with damage-rectangle compositing and a shared-facility window manager ## Status Accepted. ## Context The kernel's only display surface was a single global text terminal (`vt`), shared by the shell, klog, and fault dumps. We want a "proper GUI" with programs (a terminal, a drawing program, …). The kernel is TempleOS-inspired: one identity-mapped address space, no userspace separation, preemptive round-robin tasks. The display must stay viable on real hardware (uncached GOP framebuffers), not just fast on QEMU. The existing cursor task already routed mouse events to a single "forward target" in anticipation of a window manager. ## Decision Introduce an overlapping-window GUI: - **Window** is the fundamental unit: a rectangular, task-owned **pixel surface** composited onto the fixed 800×600 canvas, with z-order. - **Every window is a raster surface.** A terminal window renders its text grid into its own pixels; a drawing program draws pixels directly. One content model. - **Damage-rectangle compositing** (not full-frame redraw) to stay real-hardware-viable. Damage granularity is **window-level first** (repaint a dirty window's whole bounds) — revisit sub-window rectangles if the console proves slow. - **Repaint** = blit the dirty window, then re-overlay any occluders above it (rectangle intersection, not subtraction). - **The window manager is a shared facility, not a task** — in a single address space there is no isolation to enforce, so a dedicated task only adds round-trips. - **App = a task owning one window** (no separate process concept). The console is app 0. - **Focus = click-to-focus + raise**; keyboard and mouse go to the focused window. - **The console is the launcher**; no taskbar/menu in the first pass. - **Chrome** (background, per-window title bars, later a menu) is window-manager-drawn, not windows. A title bar is a strip above a **content-only** app buffer, with title, minimize, and close. - **Restore** of minimized windows is via a console command (`windows`/`restore`) plus global **keybindings** F1–F4 (spawn terminal, focus next, minimize, close); F1–F4 are reserved and invisible to apps. - **Window buffers** are dedicated `w×h×4` buffers allocated from the page allocator (the same mechanism as the shadow backbuffer); full-screen (800×600) content is allowed. - **Drawing is explicit** — the app writes into its buffer and calls `flush()` to request a composite; there is no automatic per-tick compositing. - **App event contract** — an app's queue delivers `Key`, `Mouse { x, y, buttons, kind }` (absolute window-relative; `kind` = Move/Press/Release), `Focus(bool)`, `Close`, `Timer`, and `User(u64)`. Mouse events outside the focused window's content bounds are suppressed. - **Minimum window size** is 64×64 content. - **Window lifecycle** — a window is created by and bound to its task: it is freed (buffer returned) when the task exits, via a reap hook. Close is cooperative: `Close` is delivered and the app exits; three F4 presses in quick succession force-teardown (free the window, kill the task). The console (app 0) never closes. - **Placement** — new windows cascade (+24px each, wrapping) and are focused and raised on creation; the console is full-canvas at (0,0). Windows are movable by dragging the title bar (clamped to the canvas); resize is deferred. ## Consequences - Positive: one content model, one compositing path, minimal concepts. - Negative: window-level damage means a full-screen console repaints its whole rectangle per keystroke — accepted for now, revisitable. - Negative: windows are fixed-size initially (no resize). - The existing `vt` dirty-cell path is demoted to a per-terminal-window trigger; the window manager becomes the only writer of the framebuffer (plus the cursor overlay). - Open (not yet decided): the save/image-format + image-viewer design (deferred). The terminal-app design is captured in ADR 0005.