redox-wayland-compositor/docs/phase13-1-real-client-simple-window.md
Votre Nom 530d022840 Phase 13.1 — port simple_window comme premier client tiers
Crate redox-wl-real-client-simple-window : port Redox de l'exemple
upstream wayland-rs/wayland-client/examples/simple_window.rs.
Premier client que nous n'avons PAS écrit pour valider notre compositor,
donc révélateur des paths protocolaires non anticipés.

Code upstream préservé verbatim sauf 4 adaptations Redox justifiées
dans le doc :
- Connection::connect_to_env() → UnixStream::connect(SOCKET_PATH)
  car WAYLAND_DISPLAY pas garanti dans l'init Redox.
- tempfile::tempfile() → libc::shm_open + ftruncate + mmap car
  O_TMPFILE/mkostemp non garantis par relibc.
- Attente initiale 50×100ms sur l'existence du socket (lancement
  parallèle compositor + client dans init script).
- Logs tee stdout + /scheme/debug pour observer côté serial host.

L'algorithme draw() gradient ARGB, les Dispatch impls, le delegate_noop!,
init_xdg_surface, Close/ESC sont conservés ligne pour ligne. Tout bug
observé sera donc attribuable au compositor, pas au port.

Cross-compile via `redoxer build --release` : 1.1 Mo, ELF statique,
0 warning, 0 erreur (testé 2026-05-15).

Doc phase13-1-real-client-simple-window.md : justifications des 4
adaptations, procédure runtime make qemu, 6 critères d'observation
pour la 13.1.b runtime à venir.

Runtime non validé (exige make qemu interactif) — sera consigné en
phase 13.1.b après test utilisateur.

Leyoda 2026 – GPLv3
2026-05-15 08:15:20 +02:00

8 KiB
Raw Blame History

Phase 13.1 — Premier client tiers : simple_window de wayland-rs

Document produit le 2026-05-15 dans le cadre du plan directeur REDOX_COSMIC_XWAYLAND_RS_PLAN.md.

Scope strict :

  • Porter l'exemple wayland-rs/wayland-client/examples/simple_window.rs en crate Redox autonome (redox-wl-real-client-simple-window).
  • Cross-compiler via redoxer build pour x86_64-unknown-redox.
  • Documenter la procédure runtime (image bootable + make qemu).
  • Cette phase ne valide pas encore le rendu : elle prépare le test. Le runtime sera observé et l'observabilité des bugs sera consignée dans une phase 13.1.b suivante.

Hors scope 13.1 : modifier le code de l'exemple upstream pour contourner un manque du compositor. Si l'exemple échoue, le verdict est "le compositor doit s'adapter au client standard", pas l'inverse. Seules les 4 adaptations listées ci-dessous (justifiées par l'environnement Redox) sont autorisées.

Pourquoi cet exemple, et pas un autre

simple_window.rs est :

  • Officiel upstream wayland-rs — donc représentatif du standard.
  • Pur-Rust — cross-compilable via redoxer sans toucher au sysroot.
  • Minimal mais réaliste : wl_compositor + wl_shm + xdg_wm_base
    • xdg_toplevel + wl_seat + wl_keyboard. Tous nos chemins critiques sont exercés.
  • Pas écrit par nous : c'est sa principale qualité. Nos propres clients de test (phases 6.x et 7.x) ont été conçus pour valider des paths particuliers du compositor — ils ne révèlent pas les paths qu'on n'a pas anticipés. Un client tiers le fait par construction.

Alternatives écartées :

  • list_globals.rs (74 lignes) : trop simple, ne stresse pas xdg-shell.
  • weston-simple-shm (C) : exige libwayland-client.so, non porté sur Redox.
  • smithay-client-toolkit/examples/simple_window : ajoute une dépendance importante (sctk) qui dépasse le périmètre 13.1. À reprendre en 13.2.
  • GTK4 client : ratera immédiatement sur dmabuf, decoration, subsurface. À garder pour une phase 13.4+ après durcissement.

Les 4 adaptations Redox

Toute différence vs l'upstream doit être justifiée par l'environnement, pas par un manque du compositor. Liste exhaustive :

  1. Connection::connect_to_env()UnixStream::connect(SOCKET_PATH). Justification : sous Redox, WAYLAND_DISPLAY n'est pas garanti dans l'environnement des processus lancés par un script init. Connexion explicite au socket connu.
  2. tempfile::tempfile()libc::shm_open + ftruncate + mmap. Justification : tempfile repose sur O_TMPFILE ou mkostemp qui ne sont pas garantis par relibc. On utilise le pattern que nos clients de test 6.x/7.x utilisent déjà — c'est la voie Redox-stable.
  3. Petite attente sur l'existence du socket (50×100 ms). Justification : compositor et client sont lancés en parallèle par l'init Redox ; sans poll, le client lose une race au démarrage.
  4. Logs tee sur stdout + /scheme/debug. Justification : permet d'observer le client depuis le terminal host (serial) même si on lance le compositor sur un VT et le client sur un autre.

Tout le reste — Dispatch, delegate_noop!, init_xdg_surface, l'algorithme draw() gradient ARGB, la gestion Close/ESC — est verbatim upstream.

Compilation

cd ~/Projets/Redox/redox-wayland-compositor/crates/redox-wl-real-client-simple-window
redoxer build --release

Sortie attendue (testée 2026-05-15) :

  • target/x86_64-unknown-redox/release/redox-wl-real-client-simple-window
  • ~1.1 Mo, ELF 64-bit statically linked
  • 0 warning, 0 erreur

cargo +nightly check natif fonctionne aussi pour smoke-check syntaxique, mais ne produit pas un binaire utilisable.

Procédure de test runtime

Le compositor a besoin d'un vrai framebuffer Redox + d'inputd actif. La voie validée est make qemu sur une image qui contient le compositor ET le client copiés dans /usr/bin.

Étape 1 — copier les deux binaires dans l'image Redox

mkdir -p /tmp/redox-mnt
~/Projets/Redox/redox-src/build/fstools/bin/redoxfs \
    ~/Projets/Redox/redox-src/build/x86_64/desktop/harddrive.img \
    /tmp/redox-mnt &
sleep 2

# compositor (déjà cross-compilé en phase 6.4)
cp ~/Projets/Redox/redox-wayland-compositor/crates/redox-wl-compositor/target/x86_64-unknown-redox/release/redox-wl-compositor \
   /tmp/redox-mnt/usr/bin/

# le client tiers
cp ~/Projets/Redox/redox-wayland-compositor/crates/redox-wl-real-client-simple-window/target/x86_64-unknown-redox/release/redox-wl-real-client-simple-window \
   /tmp/redox-mnt/usr/bin/

fusermount -u /tmp/redox-mnt
rmdir /tmp/redox-mnt

Étape 2 — boot Redox sous QEMU

cd ~/Projets/Redox/redox-src
make qemu audio=no QEMU_USER_FLAGS="-k fr"

Une fois Redox bootée :

  • Ctrl+Alt+F2 → bascule sur VT 2 (console texte, sans Orbital)
  • login root / password

Étape 3 — lancer compositor + client

Dans le shell Redox sur VT 2 :

# compositor en background
RUST_LOG=info redox-wl-compositor &

# attendre ~1 s pour que le socket soit bound
# (le client poll de toute façon — c'est juste pour rendre la séquence
# lisible dans les logs)
sleep 1

# le client
redox-wl-real-client-simple-window

Étape 4 — observations à consigner

À chaque session de test, noter dans une section "Observation" du prochain doc (13.1.b) :

  1. Connexion : le client connecte-t-il ([real-client] entering event loop apparaît) ?
  2. Globals reçus : le client log-t-il que wl_compositor, wl_shm, wl_seat, xdg_wm_base sont bind ? (Côté compositor : xdg_wm_base.create_xdg_surface doit logger en debug.)
  3. Configure initial : le client ack-t-il un xdg_surface.configure ? Si non, on a un bug dans notre GetToplevel handler.
  4. Premier commit pixel : la fenêtre apparaît-elle à l'écran ? Gradient ARGB visible ? Si la fenêtre est noire ou corrompue, comparer le pattern au screenshot upstream (gradient diagonal rouge/vert/bleu).
  5. Input : ESC ferme-t-il le client proprement ?
  6. Sortie : le client termine-t-il sur [real-client] PASS côté serial ?

Lister explicitement les comportements qui dévient de l'attendu.

Risques techniques anticipés

À voir avec le runtime — ne pas tirer de conclusion avant.

  • get_xdg_surface sans set_role : on n'envoie pas d'erreur pour les rôles incompatibles, donc OK probablement.
  • Initial configure suggestion : on envoie (640, 480) en suggestion, l'exemple upstream commit son buffer 320×240 — c'est légal spec mais notre logique de raise/positionnement utilise la taille de buffer, à voir si ça pose problème.
  • wl_keyboard.enter requis pour que la key ESC remonte : notre routing input via focused_client_id (phase 7.6) devrait envoyer le keyboard.enter à la fenêtre quand elle reçoit le focus initial. À observer.
  • xdg_toplevel.close jamais émis par notre compositor : l'exemple upstream s'attend à recevoir un Close quand l'utilisateur clique sur un bouton de fermeture. Comme nous n'avons pas de décoration, ce path est mort-né — donc la seule sortie possible est ESC.
  • Buffer fd via shm_open : la mémoire reste vivante après munmap côté client tant que le compositor garde le fd. Notre ShmPool::new fait un mmap côté serveur, donc OK.

Critère de fin 13.1

Le binaire redox-wl-real-client-simple-window :

  1. Compile pour x86_64-unknown-redox via redoxer build --release, sans warning ni erreur.
  2. Vit dans crates/redox-wl-real-client-simple-window/ avec son propre Cargo.toml.
  3. Préserve le code upstream verbatim sauf pour les 4 adaptations Redox justifiées ci-dessus.
  4. La procédure runtime est documentée et reproductible.

Validé au niveau compilation et préparation (2026-05-15). Runtime à observer dans la phase 13.1.b après test interactif.

Code

crates/redox-wl-real-client-simple-window/      # nouvelle crate
docs/phase13-1-real-client-simple-window.md     # ce document