test: introspect Wayland globals exposés par le compositor
Mini-binaire redox-wl-test-introspect (~210 lignes) qui se connecte au socket, énumère via wl_registry tous les globals advertised, compare à un catalogue de 21 protocoles attendus par les toolkits modernes (COSMIC, GTK4, Qt5) et rapporte présents / manquants critiques / manquants optionnels. Rapport runtime (docs/phase7-9-introspect-report.txt) : - 4 présents : wl_compositor v5, wl_shm v1, wl_seat v7, xdg_wm_base v5 - 6 critiques manquants pour COSMIC : • wl_subcompositor • wl_output • wl_data_device_manager • zxdg_decoration_manager_v1 • zwp_linux_dmabuf_v1 • zwlr_layer_shell_v1 - 11 optionnels manquants : viewporter, fractional_scale, presentation, tablet, primary_selection, output_manager, activation, cursor_shape, exporter, relative_pointer, pointer_constraints Utilisé pour anticiper les manques avant d'attaquer COSMIC. Roadmap proche : prioriser wl_output + wl_subcompositor + wl_data_device (core 8.x), puis decoration + dmabuf + layer_shell pour COSMIC. Leyoda 2026 – GPLv3
This commit is contained in:
parent
1689b93d9b
commit
2150f31d82
3 changed files with 350 additions and 0 deletions
9
crates/redox-wl-test-introspect/Cargo.toml
Normal file
9
crates/redox-wl-test-introspect/Cargo.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "redox-wl-test-introspect"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
wayland-client = { path = "../../../wayland-rs/wayland-client", default-features = false }
|
||||
wayland-backend = { path = "../../../wayland-rs/wayland-backend", default-features = false }
|
||||
libc = "0.2"
|
||||
279
crates/redox-wl-test-introspect/src/main.rs
Normal file
279
crates/redox-wl-test-introspect/src/main.rs
Normal file
|
|
@ -0,0 +1,279 @@
|
|||
//! Introspection des globals Wayland exposés par le compositor.
|
||||
//!
|
||||
//! Se connecte à `/tmp/redox-wl-comp.sock`, fait un roundtrip pour
|
||||
//! capturer tous les `wl_registry.global` events, puis :
|
||||
//! 1. Liste les globals advertised (name + version)
|
||||
//! 2. Compare à un catalogue de protocoles attendus pour
|
||||
//! COSMIC / GTK4 / Qt5 / divers toolkits Wayland modernes
|
||||
//! 3. Imprime un rapport OK / MISSING / EXTRA
|
||||
//!
|
||||
//! Sert à anticiper les manques avant d'attaquer un vrai toolkit.
|
||||
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
use std::os::unix::net::UnixStream;
|
||||
use std::process::ExitCode;
|
||||
use std::sync::{Mutex, OnceLock};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use wayland_client::{
|
||||
Connection, Dispatch, EventQueue, QueueHandle,
|
||||
backend::Backend,
|
||||
protocol::wl_registry,
|
||||
};
|
||||
|
||||
const SOCKET_PATH: &str = "/tmp/redox-wl-comp.sock";
|
||||
|
||||
struct DebugSink(Mutex<Option<std::fs::File>>);
|
||||
impl DebugSink {
|
||||
fn new() -> Self {
|
||||
Self(Mutex::new(
|
||||
OpenOptions::new().write(true).open("/scheme/debug").ok(),
|
||||
))
|
||||
}
|
||||
fn writeln(&self, s: &str) {
|
||||
println!("{s}");
|
||||
if let Ok(mut g) = self.0.lock() {
|
||||
if let Some(f) = g.as_mut() {
|
||||
let _ = writeln!(f, "{s}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fn dlog(s: &str) {
|
||||
static SINK: OnceLock<DebugSink> = OnceLock::new();
|
||||
SINK.get_or_init(DebugSink::new).writeln(s);
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Introspect {
|
||||
globals: Vec<(String, u32)>,
|
||||
}
|
||||
|
||||
impl Dispatch<wl_registry::WlRegistry, ()> for Introspect {
|
||||
fn event(
|
||||
state: &mut Self,
|
||||
_r: &wl_registry::WlRegistry,
|
||||
event: wl_registry::Event,
|
||||
_data: &(),
|
||||
_conn: &Connection,
|
||||
_qh: &QueueHandle<Self>,
|
||||
) {
|
||||
if let wl_registry::Event::Global {
|
||||
name: _,
|
||||
interface,
|
||||
version,
|
||||
} = event
|
||||
{
|
||||
state.globals.push((interface, version));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Catalogue de protocoles attendus par les toolkits modernes.
|
||||
/// Le 3e élément est une description courte de pourquoi c'est utile.
|
||||
const EXPECTED: &[(&str, &str, &str)] = &[
|
||||
// --- core wayland ---
|
||||
("wl_compositor", "core", "surfaces + regions"),
|
||||
("wl_shm", "core", "shared memory buffers"),
|
||||
("wl_seat", "core", "input devices (kbd/ptr)"),
|
||||
("wl_subcompositor", "core", "sub-surfaces"),
|
||||
("wl_output", "core", "monitors info (geometry, scale, mode)"),
|
||||
("wl_data_device_manager", "core", "clipboard + DnD"),
|
||||
// --- xdg-shell ---
|
||||
("xdg_wm_base", "stable", "window management (toplevel + popup)"),
|
||||
// --- protocoles externes très demandés ---
|
||||
(
|
||||
"zxdg_decoration_manager_v1",
|
||||
"unstable v1",
|
||||
"CSD vs SSD — GTK/Qt négocient ici qui dessine la barre de titre",
|
||||
),
|
||||
(
|
||||
"wp_viewporter",
|
||||
"stable",
|
||||
"HiDPI cropping/scaling — beaucoup de toolkits l'utilisent",
|
||||
),
|
||||
(
|
||||
"wp_fractional_scale_manager_v1",
|
||||
"v1",
|
||||
"fractional scaling (125%, 150%) — COSMIC, GNOME récent",
|
||||
),
|
||||
(
|
||||
"zwp_linux_dmabuf_v1",
|
||||
"unstable v1",
|
||||
"dmabuf import (GPU buffers) — requis pour tout GL/Vulkan",
|
||||
),
|
||||
(
|
||||
"wp_presentation",
|
||||
"stable",
|
||||
"timing précis de présentation — média players, jeux",
|
||||
),
|
||||
(
|
||||
"zwp_tablet_manager_v2",
|
||||
"unstable v2",
|
||||
"tablettes graphiques + stylus",
|
||||
),
|
||||
(
|
||||
"zwp_primary_selection_device_manager_v1",
|
||||
"unstable v1",
|
||||
"clipboard middle-click (style X11)",
|
||||
),
|
||||
(
|
||||
"zxdg_output_manager_v1",
|
||||
"unstable v1",
|
||||
"monitor info riche (xdg_output : logical position + size)",
|
||||
),
|
||||
(
|
||||
"zwlr_layer_shell_v1",
|
||||
"wlroots v1",
|
||||
"barres de tâches / overlays — REQUIS pour COSMIC panel",
|
||||
),
|
||||
(
|
||||
"xdg_activation_v1",
|
||||
"v1",
|
||||
"focus stealing prevention — toolkits modernes",
|
||||
),
|
||||
(
|
||||
"wp_cursor_shape_manager_v1",
|
||||
"v1",
|
||||
"curseurs serveur-side (alternative à set_cursor)",
|
||||
),
|
||||
(
|
||||
"zxdg_exporter_v2",
|
||||
"unstable v2",
|
||||
"exporter de handle pour foreign-toplevel",
|
||||
),
|
||||
(
|
||||
"zwp_relative_pointer_manager_v1",
|
||||
"unstable v1",
|
||||
"pointeur relatif (jeux, FPS)",
|
||||
),
|
||||
(
|
||||
"zwp_pointer_constraints_v1",
|
||||
"unstable v1",
|
||||
"lock/confine pointer (jeux)",
|
||||
),
|
||||
];
|
||||
|
||||
fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
dlog("[introspect] connect to compositor");
|
||||
for _ in 0..50 {
|
||||
if std::path::Path::new(SOCKET_PATH).exists() {
|
||||
break;
|
||||
}
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
}
|
||||
let stream = UnixStream::connect(SOCKET_PATH)?;
|
||||
let backend = Backend::connect(stream)?;
|
||||
let conn = Connection::from_backend(backend);
|
||||
let mut event_queue: EventQueue<Introspect> = conn.new_event_queue();
|
||||
let qh = event_queue.handle();
|
||||
let _registry = conn.display().get_registry(&qh, ());
|
||||
|
||||
let mut state = Introspect::default();
|
||||
// 2 roundtrips pour être sûr d'avoir tous les globals (le serveur
|
||||
// peut les advertise en plusieurs batches)
|
||||
event_queue.roundtrip(&mut state)?;
|
||||
event_queue.roundtrip(&mut state)?;
|
||||
|
||||
dlog("");
|
||||
dlog("==================================================");
|
||||
dlog("Introspection compositor Wayland — rapport");
|
||||
dlog("==================================================");
|
||||
dlog("");
|
||||
dlog(&format!(
|
||||
"Globals annoncés par le compositor ({}):",
|
||||
state.globals.len()
|
||||
));
|
||||
let mut sorted: Vec<(String, u32)> = state.globals.clone();
|
||||
sorted.sort_by(|a, b| a.0.cmp(&b.0));
|
||||
for (iface, ver) in &sorted {
|
||||
dlog(&format!(" • {iface} v{ver}"));
|
||||
}
|
||||
dlog("");
|
||||
dlog("Comparaison au catalogue COSMIC/GTK4/Qt5 :");
|
||||
dlog("");
|
||||
|
||||
let mut present_count = 0usize;
|
||||
let mut missing_critical = Vec::new();
|
||||
let mut missing_optional = Vec::new();
|
||||
|
||||
for (iface, kind, why) in EXPECTED {
|
||||
let found = state.globals.iter().find(|(i, _)| i == iface);
|
||||
match found {
|
||||
Some((_, v)) => {
|
||||
dlog(&format!(" [ OK ] {iface} v{v} — {why}"));
|
||||
present_count += 1;
|
||||
}
|
||||
None => {
|
||||
let line = format!(" [MISS] {iface} ({kind}) — {why}");
|
||||
dlog(&line);
|
||||
// Critiques pour COSMIC = layer-shell + dmabuf + decoration
|
||||
if iface.contains("layer_shell")
|
||||
|| iface.contains("dmabuf")
|
||||
|| iface.contains("decoration")
|
||||
|| iface.contains("data_device")
|
||||
|| iface.contains("wl_output")
|
||||
|| iface.contains("wl_subcompositor")
|
||||
{
|
||||
missing_critical.push(*iface);
|
||||
} else {
|
||||
missing_optional.push(*iface);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Globaux exposés non listés (potentiellement spécifiques au compositor)
|
||||
let extras: Vec<&(String, u32)> = state
|
||||
.globals
|
||||
.iter()
|
||||
.filter(|(i, _)| !EXPECTED.iter().any(|(e, _, _)| e == i))
|
||||
.collect();
|
||||
if !extras.is_empty() {
|
||||
dlog("");
|
||||
dlog("Globaux exposés hors catalogue (custom / non listés ici) :");
|
||||
for (i, v) in &extras {
|
||||
dlog(&format!(" • {i} v{v}"));
|
||||
}
|
||||
}
|
||||
|
||||
dlog("");
|
||||
dlog("==================================================");
|
||||
dlog(&format!(
|
||||
"RÉSUMÉ : {} présents / {} attendus",
|
||||
present_count,
|
||||
EXPECTED.len()
|
||||
));
|
||||
dlog(&format!(
|
||||
" ❌ Critiques manquants pour COSMIC : {}",
|
||||
missing_critical.len()
|
||||
));
|
||||
for i in &missing_critical {
|
||||
dlog(&format!(" - {i}"));
|
||||
}
|
||||
dlog(&format!(
|
||||
" ⚠ Optionnels manquants (toolkits dégradent) : {}",
|
||||
missing_optional.len()
|
||||
));
|
||||
for i in &missing_optional {
|
||||
dlog(&format!(" - {i}"));
|
||||
}
|
||||
dlog("==================================================");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> ExitCode {
|
||||
match run() {
|
||||
Ok(()) => {
|
||||
dlog("[introspect] PASS");
|
||||
ExitCode::SUCCESS
|
||||
}
|
||||
Err(e) => {
|
||||
dlog(&format!("[introspect] FAIL: {e}"));
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
}
|
||||
}
|
||||
62
docs/phase7-9-introspect-report.txt
Normal file
62
docs/phase7-9-introspect-report.txt
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
QEMU done
|
||||
==================================================
|
||||
[introspect] connect to compositor
|
||||
|
||||
==================================================
|
||||
Introspection compositor Wayland — rapport
|
||||
==================================================
|
||||
|
||||
Globals annoncés par le compositor (4):
|
||||
• wl_compositor v5
|
||||
• wl_seat v7
|
||||
• wl_shm v1
|
||||
• xdg_wm_base v5
|
||||
|
||||
Comparaison au catalogue COSMIC/GTK4/Qt5 :
|
||||
|
||||
[ OK ] wl_compositor v5 — surfaces + regions
|
||||
[ OK ] wl_shm v1 — shared memory buffers
|
||||
[ OK ] wl_seat v7 — input devices (kbd/ptr)
|
||||
[MISS] wl_subcompositor (core) — sub-surfaces
|
||||
[MISS] wl_output (core) — monitors info (geometry, scale, mode)
|
||||
[MISS] wl_data_device_manager (core) — clipboard + DnD
|
||||
[ OK ] xdg_wm_base v5 — window management (toplevel + popup)
|
||||
[MISS] zxdg_decoration_manager_v1 (unstable v1) — CSD vs SSD — GTK/Qt négocient ici qui dessine la barre de titre
|
||||
[MISS] wp_viewporter (stable) — HiDPI cropping/scaling — beaucoup de toolkits l'utilisent
|
||||
[MISS] wp_fractional_scale_manager_v1 (v1) — fractional scaling (125%, 150%) — COSMIC, GNOME récent
|
||||
[MISS] zwp_linux_dmabuf_v1 (unstable v1) — dmabuf import (GPU buffers) — requis pour tout GL/Vulkan
|
||||
[MISS] wp_presentation (stable) — timing précis de présentation — média players, jeux
|
||||
[MISS] zwp_tablet_manager_v2 (unstable v2) — tablettes graphiques + stylus
|
||||
[MISS] zwp_primary_selection_device_manager_v1 (unstable v1) — clipboard middle-click (style X11)
|
||||
[MISS] zxdg_output_manager_v1 (unstable v1) — monitor info riche (xdg_output : logical position + size)
|
||||
[MISS] zwlr_layer_shell_v1 (wlroots v1) — barres de tâches / overlays — REQUIS pour COSMIC panel
|
||||
[MISS] xdg_activation_v1 (v1) — focus stealing prevention — toolkits modernes
|
||||
[MISS] wp_cursor_shape_manager_v1 (v1) — curseurs serveur-side (alternative à set_cursor)
|
||||
[MISS] zxdg_exporter_v2 (unstable v2) — exporter de handle pour foreign-toplevel
|
||||
[MISS] zwp_relative_pointer_manager_v1 (unstable v1) — pointeur relatif (jeux, FPS)
|
||||
[MISS] zwp_pointer_constraints_v1 (unstable v1) — lock/confine pointer (jeux)
|
||||
|
||||
==================================================
|
||||
RÉSUMÉ : 4 présents / 21 attendus
|
||||
❌ Critiques manquants pour COSMIC : 6
|
||||
- wl_subcompositor
|
||||
- wl_output
|
||||
- wl_data_device_manager
|
||||
- zxdg_decoration_manager_v1
|
||||
- zwp_linux_dmabuf_v1
|
||||
- zwlr_layer_shell_v1
|
||||
⚠ Optionnels manquants (toolkits dégradent) : 11
|
||||
- wp_viewporter
|
||||
- wp_fractional_scale_manager_v1
|
||||
- wp_presentation
|
||||
- zwp_tablet_manager_v2
|
||||
- zwp_primary_selection_device_manager_v1
|
||||
- zxdg_output_manager_v1
|
||||
- xdg_activation_v1
|
||||
- wp_cursor_shape_manager_v1
|
||||
- zxdg_exporter_v2
|
||||
- zwp_relative_pointer_manager_v1
|
||||
- zwp_pointer_constraints_v1
|
||||
==================================================
|
||||
[introspect] PASS
|
||||
==================================================
|
||||
Loading…
Add table
Add a link
Reference in a new issue