Files
RedBear-OS/local/docs/WAYLAND-IMPLEMENTATION-PLAN.md
T
kellito 02fe432c17 docs: stale-doc round-4 cleanup (CONSOLE-TO-KDE + WAYLAND plan)
Round-4 stale-doc audit (2026-07-26) found that several docs
contradict the v5.4 canonical authority (DRIVER-MANAGER-MIGRATION-PLAN).
This commit addresses two of the cleanup items:

1. CONSOLE-TO-KDE-DESKTOP-PLAN.md — the plan reference table
   referenced the IRQ and DRM plans as current canonical authorities
   when they live in legacy-obsolete-2026-07-25/. Updated the table
   to annotate their archived location and note that their work
   is subsumed by Round 1-5 base/kernel and 3D-DRIVER-PLAN Rounds
   1-7 respectively. Also noted WAYLAND-IMPLEMENTATION-PLAN.md's
   status table is superseded by 3D-DRIVER-PLAN.md and added
   3D-DRIVER-PLAN.md as the canonical single coherent post-Round-7
   plan.

2. WAYLAND-IMPLEMENTATION-PLAN.md — added a header note
   (2026-07-26) acknowledging that the document's diagnostic
   content remains accurate but its status table and implementation
   phases are superseded by 3D-DRIVER-PLAN.md Rounds 1-7. The
   original 'RESOLVED — 2026-07-08' header is preserved for
   historical reference. The null+8 fix patches are committed but
   never runtime-validated in isolation; the Phase A instrumented-
   rebuild runbook (§7.1-7.4) remains the prerequisite for any
   further status claims.

Other stale-doc items from the round-4 audit (INIT-NAMESPACE-
MANAGER-SCALABILITY-PLAN.md, WIFI-IMPLEMENTATION-PLAN.md,
QUIRKS-IMPROVEMENT-PLAN.md, INPUT-STACK-LINUX-ALIGNMENT-PLAN.md,
README.md version refs) are tracked for follow-up in the
v5.5 plan update (next commit). The evdevd input-event logging
fix and the init/submodule/.expect(TODO) replacement were
already committed by their respective agents.
2026-07-26 19:54:42 +09:00

187 lines
8.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Red Bear OS Wayland Implementation Plan
> **Note (2026-07-26):** This document's diagnostic content (§§12, evidence chain,
> crash analysis) remains accurate. The **status table and implementation phases**
> below are **superseded** by `local/docs/3D-DRIVER-PLAN.md` Rounds 17
> (2026-07-26). The null+8 fix patches are committed in source
> (qtwaylandscanner + libwayland) but **never runtime-validated in isolation**.
> The Phase A instrumented-rebuild runbook (§7.17.4) is the prerequisite for
> any further status claims.
**Original header** (kept for historical reference):
# Red Bear OS Wayland Implementation Plan (RESOLVED — 2026-07-08)
**Status**: Wayland subsystem builds. Qt6 Wayland, Mesa EGL+GBM+GLES2, KWin building.
Hardware compositor validation pending. No framebuffer fallback — Wayland-only path.
**Canonical desktop path**: see `CONSOLE-TO-KDE-DESKTOP-PLAN.md` for the active plan.
**Original plan below is kept for historical context.**
`wl_proxy_add_listener`) is a bug that must be fixed at the source — in Qt6's auto-generated
Wayland wrappers or in the relibc/libwayland client stack.
**Reasoning:**
- Qt6, KF6, and KWin are Wayland-native components. Making them work through a framebuffer
abstraction adds complexity without solving the real problem.
- The `redbear-compositor` is protocol-compliant and serves 8 Wayland globals. It does not
crash. The crash is entirely client-side (Qt6 QPA plugin initialization).
- Every workaround (offscreen QPA, redox QPA shim, D-Bus environment overrides) defers the
inevitable: Qt6 Wayland must work on Redox.
**Removed workarounds:**
- ~~`QT_QPA_PLATFORM=redox` in greeter-ui main.cpp~~ — removed; greeter must use Wayland
- kded6 temporarily uses `offscreen` via `#ifdef Q_OS_REDOX` and D-Bus service `env` until
the Qt6 Wayland null+8 crash is fixed. kded6 is a headless D-Bus daemon — using Wayland
adds no functionality.
## Current Blocker: Qt6 Wayland Client Crash
### Crash Signature
```
Page fault: 0000000000000008 US
RAX: 0x0000000000000000 (NULL base pointer)
RDX: 0x0000000000000008 (value being written)
```
This is `proxy->object.implementation = listener` in `wl_proxy_add_listener()`
where `proxy` is NULL. Offset 8 from NULL = `object.implementation` field
in `wl_object` struct, which is at offset 0 of `wl_proxy`.
### Ruled Out
| Hypothesis | Verdict | Evidence |
|-----------|---------|----------|
| relibc `calloc` doesn't zero | **FALSE** | `header/stdlib/mod.rs:276``ptr.write_bytes(0, size)` runs unconditionally |
| Compositor protocol bug | **FALSE** | Compositor doesn't crash; client crashes before any compositor events exchanged |
| `wl_display_connect()` returns NULL | **FALSE** | Qt checks: `if (mDisplay) setupConnection()` |
| `wl_display_get_registry()` returns NULL | **FALSE** | My null guard `if (!registry) _exit(1)` catches this |
| libwayland `proxy_create()` returns NULL | **UNLIKELY** | Only fails on OOM or `wl_map_insert_new` failure; Qt would catch NULL |
### Most Likely Cause
The crash is in `QWaylandDisplay::init(registry)``wl_registry_add_listener()`.
The `registry` pointer is valid (caught by null guard), but the **Qt6 object wrapping it**
may have internal NULL members. Specifically, the auto-generated `QtWayland::wl_registry`
wrapper stores the C `wl_registry*` in `m_wl_registry`. If `this` (the QWaylandDisplay
object) is partially constructed when `init_listener()` runs, `m_wl_registry` could be
uninitialized.
Alternatively: the crash may be in a **subsequent** proxy creation — Qt6 binds `wl_compositor`,
`wl_shm`, or other globals during initialization, and one of those proxy creations returns
NULL that Qt doesn't check.
## Implementation Plan
### Phase A: Diagnose Exact Crash Point (1-2 hours)
1. Add `fprintf(stderr, "registry=%p this=%p\n", registry, this)` before `init(registry)`
in `qwaylanddisplay.cpp:setupConnection()`
2. Add `fprintf(stderr, "m_wl_registry=%p\n", m_wl_registry)` at entry of `init_listener()`
in generated `qwayland-wayland.cpp`
3. Add null guards at every `wl_registry_add_listener` and `wl_proxy_add_listener` call site
4. Rebuild, boot, observe which fprintf appears before the crash
### Phase B: Add Null Safety to Qt6 Generated Wrappers (2-4 hours)
The `qtwaylandscanner` tool generates wrapper code from Wayland XML protocol definitions.
The generated `init()` and `init_listener()` functions assume non-null proxies.
1. Patch `qtwaylandscanner` to emit null-checks before each `wl_*_add_listener()` call
2. Or: patch the generated output directly in the build tree
3. Add `if (!m_wl_registry) { qWarning(...); return; }` guards
### Phase C: Audit libwayland Client Initialization (2-4 hours)
1. Add logging to `proxy_create()` — log every proxy creation with pointer value
2. Add logging to `wl_proxy_add_listener()` — log proxy pointer
3. Verify `factory->display` is never NULL at `proxy_create:483`
4. Check if `pthread_mutex_lock`/`pthread_mutex_unlock` works correctly on Redox
(mutex corruption could cause `wl_map_insert_new` to return 0)
### Phase D: Fix Root Cause (4-8 hours)
Based on Phase A-B-C findings, implement the actual fix:
- If null proxy: fix the creation path
- If null `factory->display`: fix the display initialization
- If mutex issue: fix relibc pthread
- If Qt6 wrapper bug: upstream the null-safety patch
### Phase E: Remove Workarounds (1 hour)
Once Qt6 Wayland works:
1. Remove `QT_QPA_PLATFORM=redox` from `greeter-ui/main.cpp`
2. Remove `Environment=QT_QPA_PLATFORM=offscreen` from D-Bus kded6 service
3. Remove `QT_QPA_PLATFORM=offscreen` from `redbear-kde-session`
4. Let kded6 and greeter-ui use native Wayland
## Compositor Status
The `redbear-compositor` is **protocol-compliant** and **runtime-proven** (QEMU).
### Globals Served (8)
| Global | Version | Status |
|--------|---------|--------|
| `wl_compositor` | 4 | ✅ Implemented |
| `wl_shm` | 1 | ✅ Implemented (ARGB8888, XRGB8888) |
| `wl_shell` | 1 | ✅ Implemented |
| `wl_seat` | 5 | ✅ Name + pointer capability |
| `wl_output` | 3 | ✅ Geometry, mode, scale, done |
| `xdg_wm_base` | 1 | ✅ Get/surface/toplevel + configure |
| `wl_data_device_manager` | 3 | 🔧 Stub (accepts bind, no events) |
| `wl_subcompositor` | 1 | 🔧 Stub (accepts bind, no events) |
### Rendering
Framebuffer compositing via `/scheme/display` (vesad). Software only.
Hardware DRM/KMS rendering depends on `redox-drm` driver maturity.
## Evidence Model
| Class | Meaning |
|-------|---------|
| **builds** | Package compiles and stages |
| **boots** | Image reaches prompt or known runtime surface |
| **runtime-proven (QEMU)** | Works end-to-end in QEMU |
| **runtime-proven (bare metal)** | Works on real hardware |
| **validated** | Repeated proof on intended target class |
### Current Status
| Component | Class | Notes |
|-----------|-------|-------|
| `redbear-compositor` | **runtime-proven (QEMU)** | Accepts connections, composites framebuffer |
| `libwayland` client | **builds** | Upstream code; Redox eventfd patch for server only |
| `libwayland` server | **builds** | Not used — compositor is pure Rust |
| Qt6 Wayland QPA | **build-verified; runtime gated** | Crashes at null+8 during `wl_registry` init |
| KWin Wayland | **builds** | Real cmake build; blocked by Qt6Quick/QML |
| Wayland protocols | **builds** | `wayland-protocols` package builds |
## Next Milestone
**Qt6 Wayland client boots without crashing.**
Success criterion: `redbear-compositor: client 65536 connected` followed by
`redbear-compositor: dispatch` (not a page fault).
### Build Dependency Chain (Critical, discovered 2026-05-06)
When modifying libwayland source or `local/patches/libwayland/redox.patch`, the
full chain must be rebuilt:
```
libwayland recipe → repo/x86_64-unknown-redox/libwayland.pkgar
qtbase recipe → copies pkgar into sysroot → links Qt6 Wayland QPA
kf6-kded6 recipe → links against qtbase/sysroot/libwayland-client.a
```
**Failure mode**: Modifying only libwayland does NOT update qtbase's static copy
of `libwayland-client.a`. The old binary persists in qtbase's sysroot. All
three recipes must be force-rebuilt (delete `target/` directories) AND the
repo pkgar cache must be regenerated.
**Recovery**: If `repo/x86_64-unknown-redox/libwayland.pkgar` is deleted, a
backup exists at `packages/x86_64-unknown-redox/libwayland.pkgar`.