diff options
| author | salmonik <salmonik@tuta.io> | 2026-08-17 18:56:04 +0200 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-08-17 18:56:04 +0200 |
| commit | 5558e3509d020a0e021a77f0617044497b2f2aee (patch) | |
| tree | cd7b6cee9f7c327f9fae7ad9ac27602d1a97b222 /docs/adr | |
| parent | USB2/1.1 (EHCI/UHCI) drivers + real-hardware bring-up hardening (diff) | |
| download | rs-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 'docs/adr')
| -rw-r--r-- | docs/adr/0004-windowed-gui-and-compositor.md | 78 |
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 | |||
| 5 | Accepted. | ||
| 6 | |||
| 7 | ## Context | ||
| 8 | |||
| 9 | The kernel's only display surface was a single global text terminal (`vt`), | ||
| 10 | shared by the shell, klog, and fault dumps. We want a "proper GUI" with | ||
| 11 | programs (a terminal, a drawing program, …). The kernel is | ||
| 12 | TempleOS-inspired: one identity-mapped address space, no userspace | ||
| 13 | separation, preemptive round-robin tasks. The display must stay viable on | ||
| 14 | real hardware (uncached GOP framebuffers), not just fast on QEMU. The | ||
| 15 | existing cursor task already routed mouse events to a single "forward | ||
| 16 | target" in anticipation of a window manager. | ||
| 17 | |||
| 18 | ## Decision | ||
| 19 | |||
| 20 | Introduce 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). | ||
