The failure this is against is not scope creep. It is abandonment by promotion:
a thing gets built to the point where it works, the next thing becomes more
interesting, and the first is left in a corner -- in the tree, not finished, not
deleted, and not in any list. Enough of those and the tree stops matching its
own documentation.
docs/plan/1.0.md now holds the register, and it is the only place anything
half-built is listed. Four sections, because the kinds are genuinely different:
built and connected to nothing (the text layer, a font from disk, socket
activation, wait_vblank); started and stopped part-way (foundations 2-5, hybrid
H2, Schcom v0, a released PCI device that nothing brings back); named in a "what
it does not do" and still true; and frozen -- scoped, unstarted, not to be
started. The rule is that nothing enters except by being finished or deleted,
and that adding a row requires closing one.
1.0.md already said "two things in flight, never three". It was right and it was
not being followed.
Then the corners themselves, because a register written over a tree full of them
is just a longer list:
- cmd/init is deleted. Nothing had execed /bin/init since initcode.S changed
to /bin/schinit; it was built and installed on every image as an unreachable
fallback, and an unreachable fallback rots rather than saves.
- projects/schwm/ and projects/schde/ are deleted. Both said "to be deleted"
in their own first paragraph, which proves only that a directory marked for
deletion is not deleted by being marked. README-only, no code lost, and the
arguments each made are moved into wayland.md where they are still true.
- projects/schcom/schcom and schcom-demo were tracked binaries. Untracked, and
.gitignore'd.
Three code comments and one document described a boot that has not happened
since 7d44eb7. cons_serial_only starts set, but kmain clears it on its first
lines now, so the splash does not survive the boot and the kernel log is on
screen from the start. That reversal was earned by a Chromebox with no serial
port freezing at boot showing nothing at all, and the comments still argued the
losing side of it.
The site:
- a download page. One ISO, what it has actually been run on -- one machine,
under test -- Ventoy and dd, what the first boot looks like step by step,
and the build if you would rather. The support table names one Chromebox
rather than listing hardware, because one Chromebox is the entire bare-metal
record and a list would be fiction.
- Assets/usb.svg, drawn to the same rule as the other marks: two tones,
geometry only, the accent spent in one place, and that place is the activity
light because it is the part that tells you something is happening.
- Download is in both navs and is the hero's primary action; a closing band
ends the front page on it.
- the uberblock-slots and drivers-outside-the-kernel figures are gone. Three
numbers left, including the fastfetch one, which stays because it is funny.
Two things caught by rendering the pages instead of assuming: .hero p was
beating .filemeta on specificity and the file line was coming out at body size,
and the dd command was one line long enough that the card clipped it at `conv=`
-- a destructive command that can scroll half of itself out of view is a good
way to take somebody's disk. It is two lines now.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
176 lines
7.5 KiB
Markdown
176 lines
7.5 KiB
Markdown
# The GUI becomes Wayland
|
||
|
||
Schcom survives and changes its wire format. SchWM and SchDE are deleted. What
|
||
follows is why that is not a retreat, and what it costs.
|
||
|
||
Blocked on [foundations.md](foundations.md), items 1–4. **Item 1 is built** —
|
||
descriptor passing, without which no Wayland client can hand over a buffer. Item
|
||
2, a shareable memory object, is the next thing it stops at.
|
||
|
||
---
|
||
|
||
## What was deleted
|
||
|
||
`projects/schwm/` and `projects/schde/`, both README-only; no code was lost. They
|
||
are **gone from the tree now** rather than marked for deletion — a directory that
|
||
has said "to be deleted" for months is a corner, not a decision. The arguments
|
||
each made are kept below, because they are the part worth keeping.
|
||
|
||
### SchWM is not abandoned — Wayland dissolves it
|
||
|
||
In X11 the window manager is a separate privileged client because X11 puts
|
||
compositing in the server and policy nowhere. **Wayland's central decision is
|
||
that the compositor *is* the window manager**: there is no protocol by which a
|
||
second process places another's windows, and every attempt to add one has been a
|
||
private extension.
|
||
|
||
So SchWM's own argument —
|
||
|
||
> *"Compositing is mechanical and must never stall: it runs every frame and a
|
||
> mistake there is a frozen screen. Window management is policy, full of special
|
||
> cases and personal taste, and it changes constantly."*
|
||
|
||
— is a real and correct observation **about X11**, which Wayland answers a
|
||
different way. It stays worth honouring, but as a **module boundary inside
|
||
Schcom**, not a process boundary: policy in its own file behind its own
|
||
interface. Do not keep it in its own process, because the protocol to talk to it
|
||
does not exist.
|
||
|
||
### SchDE is re-sited rather than abandoned
|
||
|
||
A panel, a launcher and a wallpaper are ordinary Wayland clients using
|
||
`wlr-layer-shell` — MIT, an XML file, no dependency. They need no directory of
|
||
their own until one of them is written. SchDE's other observation stands on its
|
||
own and is recorded here so it does not go with the directory: **a GUI terminal
|
||
is not the kernel console with a window around it.** The console parses ANSI
|
||
because it draws straight to the framebuffer; a terminal client parses ANSI
|
||
itself and renders it with proportional-capable text. The two share no code.
|
||
|
||
### `projects/schinst/` stays
|
||
|
||
Its GUI was the part tied to SchWM, and that part becomes a Wayland client.
|
||
Everything else in it — the `.sip` format, `mksip`, the apply path, the
|
||
installation environment — is untouched by any of this, and remains the
|
||
best-specified unstarted work in the tree.
|
||
|
||
---
|
||
|
||
## What survives
|
||
|
||
**Schcom stays, and keeps its name.** It already owns the display, allocates and
|
||
owns client buffers, implements surface/attach/commit, routes input from
|
||
`/dev/input/eventN`, composites multiple clients bottom-to-top, and cleans up
|
||
after clients that die.
|
||
|
||
Its own README says the protocol is deliberately Wayland-shaped — surfaces rather
|
||
than windows, buffers attached and made visible only on commit, the compositor
|
||
telling clients when to draw. That was the right call and this is where it is
|
||
cashed in: **what changes is the wire format and the buffer handle, not the
|
||
architecture.**
|
||
|
||
---
|
||
|
||
## What has to exist first
|
||
|
||
Items 1–4 of [foundations.md](foundations.md), and the first three are absolute —
|
||
libwayland does not start without them.
|
||
|
||
The sharpest is descriptor passing. `wl_shm_create_pool` passes a **file
|
||
descriptor**, and there is no path in the protocol that passes an integer
|
||
instead. `struct schcom_surface`'s `handle_kind` field was written precisely so
|
||
that switching would be a new value rather than a protocol break, and it cannot
|
||
help: *our* protocol is the flexible one.
|
||
|
||
---
|
||
|
||
## Port libwayland. Do not port Weston.
|
||
|
||
**libwayland is the small piece**: a wire protocol, an object map, and an event
|
||
loop, needing `libffi` and — for the build-time scanner, on the host only —
|
||
`libexpat`. A real port, but a bounded one.
|
||
|
||
**Weston is the trap.** It arrives welded to `libinput`, `udev`, `libdrm`,
|
||
`logind`-shaped seat management and a GL renderer, and porting it means porting
|
||
Linux's device management first and finding the compositor somewhere underneath.
|
||
|
||
This is precisely the lesson already recorded twice in this tree — about
|
||
FreeBSD's `sys/dev/usb` (100k lines welded to newbus) and about FreeBSD's
|
||
`sys/netinet` (not a library; reaches into mbufs, epoch, netisr, VNET and uma).
|
||
|
||
> The tree has learned this twice. It should not pay to learn it a third time.
|
||
|
||
So **Schcom links `libwayland-server` and remains ours.** Input comes from
|
||
`/dev/input/eventN`, which already works, rather than from libinput. Output goes
|
||
through `display_ops`, which already exists.
|
||
|
||
### Software rendering first, and probably for a long time
|
||
|
||
`pixman` for composition, `wl_shm` for buffers. Mesa means EGL means `dlopen`
|
||
means a dynamic loader, and that is a large kernel project that does not have to
|
||
be on this path. Static binaries are enough to reach a working desktop; keep it
|
||
that way until something concrete demands otherwise.
|
||
|
||
### One sharp edge
|
||
|
||
`wl_keyboard` hands the client **a keymap as an XKB text blob over a file
|
||
descriptor**. A compositor cannot avoid xkbcommon by having simpler opinions
|
||
about keyboards — the protocol requires the blob.
|
||
|
||
The cheap route is one precompiled keymap string shipped in the binary, with
|
||
xkbcommon and `xkeyboard-config` deferred until more than one layout is wanted.
|
||
|
||
---
|
||
|
||
## Licensing
|
||
|
||
Checked before anything is fetched — the standing rule is that the licence goes
|
||
in `NOTICE` **before** the file is committed, not after.
|
||
|
||
| | |
|
||
|---|---|
|
||
| wayland, wayland-protocols | MIT |
|
||
| `wlr-layer-shell` | MIT |
|
||
| pixman | MIT |
|
||
| libffi | MIT |
|
||
| libxkbcommon | MIT |
|
||
| xkeyboard-config | MIT |
|
||
|
||
All Apache-2.0 compatible, all needing only a `NOTICE` entry. **Nothing here
|
||
carries the GPL problem that governs drivers**, which is a pleasant change and
|
||
worth noticing: the Wayland ecosystem is permissively licensed almost throughout,
|
||
and that is a genuine argument for it beyond any technical one.
|
||
|
||
---
|
||
|
||
## Milestones
|
||
|
||
| | |
|
||
|---|---|
|
||
| **W0** | [foundations.md](foundations.md) items 1–4, with the combined test that passes a descriptor *and* shares a `memfd` *and* binds a socket at a real path. |
|
||
| **W1** | libwayland builds and installs into the sysroot. `wayland-scanner` runs on the host. |
|
||
| **W2** | Schcom serves `wl_compositor`, `wl_shm`, `wl_surface`, `xdg_shell`. A client draws one window. |
|
||
| **W3** | `wl_seat`: keyboard and pointer, from the evdev path that exists. |
|
||
| **W4** | Two clients, focus, stacking, move and resize. **This is where SchWM's policy lives, as a file.** |
|
||
| **W5** | `wlr-layer-shell`, and a panel. This is SchDE's first pixel. |
|
||
|
||
Every milestone from W2 on is asserted **from the host, by pixel**, the way
|
||
`schcom-test` already does. The compositor's own report that it composited
|
||
something proves nothing.
|
||
|
||
---
|
||
|
||
## What it will still not do
|
||
|
||
- **No hardware acceleration.** Software rendering only, until dynamic linking
|
||
and Mesa, neither of which is on this plan.
|
||
- **No XWayland**, so no X11 clients, ever, unless someone ports it.
|
||
- **No mode setting.** Resolution stays whatever the loader asked for — see
|
||
[hybrid.md](hybrid.md), where the GPU driver's eviction is also where a modeset
|
||
API would arrive.
|
||
- **No damage tracking beyond "repaint everything"**, no multiple outputs, no
|
||
subsurfaces. Schcom's README already lists these; they are additions rather
|
||
than rewrites, which is the reason for committing to the surface/commit model
|
||
now.
|
||
- **One keyboard layout**, until xkbcommon is ported.
|
||
- **No clipboard, no drag and drop, no screen capture protocol**, none of which
|
||
W0–W5 touches.
|