summaryrefslogtreecommitdiffstats
path: root/docs/adr/0004-windowed-gui-and-compositor.md
blob: 87f637eabb2ba507c7e52afcc2cacd9917021980 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# 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.