summaryrefslogtreecommitdiffstats
path: root/docs/adr/0004-windowed-gui-and-compositor.md
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-17 18:56:04 +0200
committersalmonik <salmonik@tuta.io>2026-08-17 18:56:04 +0200
commit5558e3509d020a0e021a77f0617044497b2f2aee (patch)
treecd7b6cee9f7c327f9fae7ad9ac27602d1a97b222 /docs/adr/0004-windowed-gui-and-compositor.md
parentUSB2/1.1 (EHCI/UHCI) drivers + real-hardware bring-up hardening (diff)
downloadrs-dos-5558e3509d020a0e021a77f0617044497b2f2aee.tar.gz
rs-dos-5558e3509d020a0e021a77f0617044497b2f2aee.zip
Windowed GUI: wm module, input routing, and the paint app
- Add the wm window-manager facility per ADR 0004: overlapping pixel-surface windows, damage-rectangle compositing, WM-drawn title bar, focus/minimize/close, and F1-F4 keybindings - Add gop shadow compositing primitives and vt::repaint_region so the console stays layer 0 beneath windows - Route mouse (absolute coords, press/release edges) and keyboard (focus-aware input pump) to the focused window - Add the rspaint drawing-program crate (pen, 8 colors, clear) and shell draw/windows/restore commands - Extend TaskMsg with AppMouse/Focus/Close and document the design in CONTEXT.md + ADR 0004
Diffstat (limited to '')
-rw-r--r--docs/adr/0004-windowed-gui-and-compositor.md78
1 files changed, 78 insertions, 0 deletions
diff --git a/docs/adr/0004-windowed-gui-and-compositor.md b/docs/adr/0004-windowed-gui-and-compositor.md
new file mode 100644
index 0000000..86e8b30
--- /dev/null
+++ b/docs/adr/0004-windowed-gui-and-compositor.md
@@ -0,0 +1,78 @@
1# ADR 0004 — Overlapping-window GUI with damage-rectangle compositing and a shared-facility window manager
2
3## Status
4
5Accepted.
6
7## Context
8
9The kernel's only display surface was a single global text terminal (`vt`),
10shared by the shell, klog, and fault dumps. We want a "proper GUI" with
11programs (a terminal, a drawing program, …). The kernel is
12TempleOS-inspired: one identity-mapped address space, no userspace
13separation, preemptive round-robin tasks. The display must stay viable on
14real hardware (uncached GOP framebuffers), not just fast on QEMU. The
15existing cursor task already routed mouse events to a single "forward
16target" in anticipation of a window manager.
17
18## Decision
19
20Introduce an overlapping-window GUI:
21
22- **Window** is the fundamental unit: a rectangular, task-owned **pixel
23 surface** composited onto the fixed 800×600 canvas, with z-order.
24- **Every window is a raster surface.** A terminal window renders its text
25 grid into its own pixels; a drawing program draws pixels directly. One
26 content model.
27- **Damage-rectangle compositing** (not full-frame redraw) to stay
28 real-hardware-viable. Damage granularity is **window-level first**
29 (repaint a dirty window's whole bounds) — revisit sub-window rectangles
30 if the console proves slow.
31- **Repaint** = blit the dirty window, then re-overlay any occluders above
32 it (rectangle intersection, not subtraction).
33- **The window manager is a shared facility, not a task** — in a single
34 address space there is no isolation to enforce, so a dedicated task only
35 adds round-trips.
36- **App = a task owning one window** (no separate process concept). The
37 console is app 0.
38- **Focus = click-to-focus + raise**; keyboard and mouse go to the focused
39 window.
40- **The console is the launcher**; no taskbar/menu in the first pass.
41- **Chrome** (background, per-window title bars, later a menu) is
42 window-manager-drawn, not windows. A title bar is a strip above a
43 **content-only** app buffer, with title, minimize, and close.
44- **Restore** of minimized windows is via a console command
45 (`windows`/`restore`) plus global **keybindings** F1–F4 (spawn terminal,
46 focus next, minimize, close); F1–F4 are reserved and invisible to apps.
47- **Window buffers** are dedicated `w×h×4` buffers allocated from the page
48 allocator (the same mechanism as the shadow backbuffer); full-screen
49 (800×600) content is allowed.
50- **Drawing is explicit** — the app writes into its buffer and calls
51 `flush()` to request a composite; there is no automatic per-tick
52 compositing.
53- **App event contract** — an app's queue delivers `Key`, `Mouse { x, y,
54 buttons, kind }` (absolute window-relative; `kind` = Move/Press/Release),
55 `Focus(bool)`, `Close`, `Timer`, and `User(u64)`. Mouse events outside
56 the focused window's content bounds are suppressed.
57- **Minimum window size** is 64×64 content.
58- **Window lifecycle** — a window is created by and bound to its task: it
59 is freed (buffer returned) when the task exits, via a reap hook. Close
60 is cooperative: `Close` is delivered and the app exits; three F4 presses
61 in quick succession force-teardown (free the window, kill the task). The
62 console (app 0) never closes.
63- **Placement** — new windows cascade (+24px each, wrapping) and are
64 focused and raised on creation; the console is full-canvas at (0,0).
65 Windows are fixed-position and fixed-size in v1: move is the first
66 post-v1 feature and resize is deferred.
67
68## Consequences
69
70- Positive: one content model, one compositing path, minimal concepts.
71- Negative: window-level damage means a full-screen console repaints its
72 whole rectangle per keystroke — accepted for now, revisitable.
73- Negative: windows are fixed-size initially (no resize).
74- The existing `vt` dirty-cell path is demoted to a per-terminal-window
75 trigger; the window manager becomes the only writer of the framebuffer
76 (plus the cursor overlay).
77- Open (not yet decided): the terminal-app design (per-instance vt + shell),
78 and the save/image-format + image-viewer design (both deferred).