fix(mirada-compositor): no pisar WAYLAND_DISPLAY antes de winit::init
winit lee WAYLAND_DISPLAY/DISPLAY para encontrar la sesión gráfica anfitriona donde anidarse. El código publicaba antes su propio socket en WAYLAND_DISPLAY, así que winit intentaba anidarse en el propio compositor —un socket que aún no atiende a nadie— y se colgaba. Ahora winit::init() va primero (conecta a la sesión real) y el socket propio + set_var se publican después. Si no hay sesión gráfica, aborta con un mensaje claro en vez de colgarse o fallar en seco. README: sección Requisitos — hace falta sesión X11/Wayland anfitriona; receta Xvfb + VNC para cajas headless. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,27 @@ Backend `winit`: corre **anidado** — una ventana dentro de tu sesión
|
|||||||
gráfica actual, X11 o Wayland. No toca DRM/KMS, así que es seguro de
|
gráfica actual, X11 o Wayland. No toca DRM/KMS, así que es seguro de
|
||||||
arrancar sin dejar la sesión.
|
arrancar sin dejar la sesión.
|
||||||
|
|
||||||
|
## Requisitos
|
||||||
|
|
||||||
|
Hace falta una **sesión gráfica anfitriona** (X11 o Wayland) donde
|
||||||
|
dibujar la ventana del compositor — es donde `winit` se anida. En un
|
||||||
|
servidor *headless* (SSH a una caja sin escritorio, `XDG_SESSION_TYPE=tty`,
|
||||||
|
sin `/dev/dri`) no hay dónde mostrar nada y el arranque aborta con un
|
||||||
|
mensaje que lo explica.
|
||||||
|
|
||||||
|
Para verlo en una caja headless: levanta un servidor X virtual y
|
||||||
|
conéctate por VNC.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
Xvfb :99 -screen 0 1280x800x24 &
|
||||||
|
x11vnc -display :99 -localhost -nopw & # luego túnel SSH al :5900
|
||||||
|
DISPLAY=:99 cargo run -p mirada-compositor
|
||||||
|
```
|
||||||
|
|
||||||
|
El backend nativo DRM/KMS —que pintaría directo en la pantalla sin
|
||||||
|
sesión anfitriona— está pendiente (ver el SDD), y de todos modos
|
||||||
|
necesitaría un `/dev/dri`.
|
||||||
|
|
||||||
## Dos modos
|
## Dos modos
|
||||||
|
|
||||||
- **Autónomo** (por defecto) — lleva un `Desktop` (de `mirada-brain`)
|
- **Autónomo** (por defecto) — lleva un `Desktop` (de `mirada-brain`)
|
||||||
|
|||||||
@@ -475,6 +475,34 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
state.apply_commands(vec![grab]);
|
state.apply_commands(vec![grab]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// El backend gráfico va primero. winit abre la ventana del compositor
|
||||||
|
// dentro de tu sesión gráfica anfitriona, y para encontrarla lee
|
||||||
|
// `WAYLAND_DISPLAY` / `DISPLAY` del entorno. Si publicáramos antes
|
||||||
|
// nuestro propio socket en `WAYLAND_DISPLAY`, winit intentaría
|
||||||
|
// anidarse en nosotros mismos —un socket que aún no atiende a nadie—
|
||||||
|
// y se quedaría colgado para siempre.
|
||||||
|
let (mut backend, mut winit) = match winit::init::<GlesRenderer>() {
|
||||||
|
Ok(pair) => pair,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("mirada-compositor · no pude abrir la ventana: {e}");
|
||||||
|
eprintln!(
|
||||||
|
" El backend `winit` necesita una sesión gráfica anfitriona\n \
|
||||||
|
(X11 o Wayland) donde dibujar la ventana del compositor.\n \
|
||||||
|
Aquí no hay ninguna: DISPLAY='{}', WAYLAND_DISPLAY='{}',\n \
|
||||||
|
XDG_SESSION_TYPE='{}'.\n \
|
||||||
|
Lánzalo desde un escritorio gráfico, o desde un servidor X\n \
|
||||||
|
virtual (Xvfb) al que te conectes por VNC.",
|
||||||
|
std::env::var("DISPLAY").unwrap_or_default(),
|
||||||
|
std::env::var("WAYLAND_DISPLAY").unwrap_or_default(),
|
||||||
|
std::env::var("XDG_SESSION_TYPE").unwrap_or_else(|_| "tty".into()),
|
||||||
|
);
|
||||||
|
return Err(e.into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ahora sí, nuestro propio socket Wayland — y `WAYLAND_DISPLAY` se
|
||||||
|
// publica *después* de winit, sólo para los clientes que lancemos
|
||||||
|
// como procesos hijos.
|
||||||
let listener = ListeningSocket::bind_auto("wayland", 1..32)?;
|
let listener = ListeningSocket::bind_auto("wayland", 1..32)?;
|
||||||
let socket_name = listener
|
let socket_name = listener
|
||||||
.socket_name()
|
.socket_name()
|
||||||
@@ -485,7 +513,6 @@ fn run() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!("mirada-compositor · escuchando en WAYLAND_DISPLAY={socket_name}");
|
println!("mirada-compositor · escuchando en WAYLAND_DISPLAY={socket_name}");
|
||||||
println!(" lanza un cliente: WAYLAND_DISPLAY={socket_name} foot");
|
println!(" lanza un cliente: WAYLAND_DISPLAY={socket_name} foot");
|
||||||
|
|
||||||
let (mut backend, mut winit) = winit::init::<GlesRenderer>()?;
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let mut clients = Vec::new();
|
let mut clients = Vec::new();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user