tawasuyu

tawasuyu/brahman

Rust 582TOML 222Markdown 73JSON 198629 Definitions

fix(mirada-compositor): backend DRM — salida garantizada + logs de teclado

Tras la primera prueba en hardware (el bucle arranca y compone el fondo,
pero el teclado no responde y no había forma de salir):

- Salida garantizada: el backend DRM se cierra solo a los 60 s (env
  MIRADA_DRM_TIMEOUT, 0 lo desactiva). Así una prueba nunca deja la
  pantalla atrapada aunque el teclado falle.
- handle_input instrumentado: registra cada dispositivo de entrada que
  libinput descubre y cada tecla con su combo y si es un atajo — para
  diagnosticar por qué no llega la entrada.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

782244b74391acc0ab7f7731edb33f939f9b84c9 · by sergio · (5 months ago) · parent fe221869d · browse the tree at this commit

Semantic delta · 2

crates/apps/mirada-compositor/src/drm_backend.rs

1 files · +58 −33

diff --git a/crates/apps/mirada-compositor/src/drm_backend.rs b/crates/apps/mirada-compositor/src/drm_backend.rs
index 78490ae..9dc2713 100644
--- a/crates/apps/mirada-compositor/src/drm_backend.rs
+++ b/crates/apps/mirada-compositor/src/drm_backend.rs
@@ -161,39 +161,48 @@ impl DrmState {
     }
 
     /// Procesa un evento de `libinput` — por ahora, sólo el teclado.
+    /// Va instrumentado: registra los dispositivos que encuentra y cada
+    /// tecla, para diagnosticar la entrada sin el hardware delante.
     fn handle_input(&mut self, event: InputEvent<LibinputInputBackend>) {
-        let InputEvent::Keyboard { event } = event else {
-            return; // puntero/táctil: pendiente
-        };
-        let Some(keyboard) = self.app.keyboard.clone() else {
-            return;
-        };
-        let code = event.key_code();
-        let key_state = event.state();
-        let pressed = key_state == KeyState::Pressed;
-        let time = self.start.elapsed().as_millis() as u32;
-        keyboard.input::<(), _>(
-            &mut self.app,
-            code,
-            key_state,
-            SERIAL_COUNTER.next_serial(),
-            time,
-            |st, mods, handle| {
-                if !pressed {
-                    return FilterResult::Forward;
-                }
-                if let Some(combo) = combo_string(mods, handle.modified_sym()) {
-                    if st.grabs.contains(&combo) {
-                        st.pending_keybind = Some(combo);
-                        return FilterResult::Intercept(());
-                    }
+        match event {
+            InputEvent::DeviceAdded { device } => {
+                eprintln!("input · dispositivo detectado: «{}»", device.name());
+            }
+            InputEvent::Keyboard { event } => {
+                let Some(keyboard) = self.app.keyboard.clone() else {
+                    eprintln!("input · ¡sin teclado en el seat!");
+                    return;
+                };
+                let code = event.key_code();
+                let key_state = event.state();
+                let pressed = key_state == KeyState::Pressed;
+                let time = self.start.elapsed().as_millis() as u32;
+                keyboard.input::<(), _>(
+                    &mut self.app,
+                    code,
+                    key_state,
+                    SERIAL_COUNTER.next_serial(),
+                    time,
+                    |st, mods, handle| {
+                        if !pressed {
+                            return FilterResult::Forward;
+                        }
+                        let combo = combo_string(mods, handle.modified_sym());
+                        let grabbed = combo.as_ref().is_some_and(|c| st.grabs.contains(c));
+                        eprintln!("input · tecla {code:?} → combo {combo:?} · atajo={grabbed}");
+                        if grabbed {
+                            st.pending_keybind = combo;
+                            return FilterResult::Intercept(());
+                        }
+                        FilterResult::Forward
+                    },
+                );
+                if let Some(combo) = self.app.pending_keybind.take() {
+                    let ev = self.app.body.keybind(combo);
+                    self.app.brain_feed(ev);
                 }
-                FilterResult::Forward
-            },
-        );
-        if let Some(combo) = self.app.pending_keybind.take() {
-            let ev = self.app.body.keybind(combo);
-            self.app.brain_feed(ev);
+            }
+            _ => {} // puntero/táctil: pendiente
         }
     }
 }
@@ -399,10 +408,21 @@ pub fn run() -> Result<(), Box<dyn Error>> {
         })
         .map_err(|e| format!("insert timer: {e}"))?;
 
+    // Salida garantizada mientras depuramos: se cierra solo a los N s
+    // (env `MIRADA_DRM_TIMEOUT`, 0 lo desactiva) — así nunca te quedas
+    // atrapado si el teclado aún no responde.
+    let timeout_secs: u64 = std::env::var("MIRADA_DRM_TIMEOUT")
+        .ok()
+        .and_then(|v| v.parse().ok())
+        .unwrap_or(60);
+
     println!("──────────────────────────────────────────────────");
     println!("mirada-compositor · escritorio en marcha sobre «{out_name}».");
     println!("   Lanza un cliente:  WAYLAND_DISPLAY={socket_name} foot");
-    println!("   Salir: Super+Shift+e.");
+    println!("   Salir: Super+Shift+e  ·  o Ctrl+C en esta TTY.");
+    if timeout_secs > 0 {
+        println!("   Se cerrará solo a los {timeout_secs}s (MIRADA_DRM_TIMEOUT=0 lo quita).");
+    }
 
     let mut state = DrmState {
         app,
@@ -419,7 +439,12 @@ pub fn run() -> Result<(), Box<dyn Error>> {
     let signal = event_loop.get_signal();
     event_loop
         .run(None, &mut state, |state| {
-            if !state.app.running {
+            let timed_out =
+                timeout_secs > 0 && state.start.elapsed() > Duration::from_secs(timeout_secs);
+            if !state.app.running || timed_out {
+                if timed_out {
+                    println!("mirada-compositor · tope de tiempo — cerrando.");
+                }
                 signal.stop();
             }
         })