feat(mirada): sesión de escritorio — autostart y conmutación de VT
Dos piezas para usar carmen como tu escritorio de verdad. Conmutación de VT — `Ctrl+Alt+Fn` salta a otra TTY y vuelve sin romper la sesión. El `SessionEvent` de `libseat` ahora hace trabajo de verdad: - al ceder la VT, pausa el `DrmDevice` y suspende `libinput`; `render()` no vuelve a tocar la GPU mientras la sesión esté cedida (`active`). - al recuperarla, reanuda `libinput`, reactiva el `DrmDevice`, llama a `DrmCompositor::reset_state` y repinta. `DrmState` conserva ahora `drm` y un clon del contexto `libinput`. Sesión — `~/.config/mirada/autostart` (un comando por línea, `#` comenta) se lanza al arrancar el backend DRM, vía un `spawn_autostart` que reusa `spawn_command`. Y `session/`: el script `mirada-session` (fija el entorno XDG y exec del compositor) y `carmen.desktop` para registrarlo en un gestor de login, más un `autostart.example`. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -630,8 +630,8 @@ fn cursor_hotspot(surface: &WlSurface) -> (i32, i32) {
|
||||
|
||||
/// Lanza un comando como proceso hijo, vía `sh -c`. El hijo hereda el
|
||||
/// entorno —`WAYLAND_DISPLAY` incluido—, así que el cliente que abra se
|
||||
/// conecta a este compositor. Lo usan la acción `spawn:…` del keymap y
|
||||
/// la variable `MIRADA_STARTUP`.
|
||||
/// conecta a este compositor. Lo usan la acción `spawn:…` del keymap, la
|
||||
/// variable `MIRADA_STARTUP` y el autoarranque.
|
||||
fn spawn_command(cmd: &str) {
|
||||
let cmd = cmd.trim();
|
||||
if cmd.is_empty() {
|
||||
@@ -643,6 +643,36 @@ fn spawn_command(cmd: &str) {
|
||||
}
|
||||
}
|
||||
|
||||
/// La ruta del archivo de autoarranque del usuario,
|
||||
/// `~/.config/mirada/autostart` — junto al keymap y las reglas.
|
||||
fn autostart_path() -> Option<std::path::PathBuf> {
|
||||
Keymap::default_path().and_then(|p| p.parent().map(|d| d.join("autostart")))
|
||||
}
|
||||
|
||||
/// Lanza los programas del archivo de autoarranque: un comando por
|
||||
/// línea, `#` comenta y las líneas en blanco se saltan. Sin archivo, no
|
||||
/// hace nada. Se llama una vez al arrancar, con el socket ya abierto.
|
||||
fn spawn_autostart() {
|
||||
let Some(path) = autostart_path() else {
|
||||
return;
|
||||
};
|
||||
let Ok(text) = std::fs::read_to_string(&path) else {
|
||||
return; // no hay archivo de autoarranque
|
||||
};
|
||||
let mut n = 0;
|
||||
for line in text.lines() {
|
||||
let line = line.trim();
|
||||
if line.is_empty() || line.starts_with('#') {
|
||||
continue;
|
||||
}
|
||||
spawn_command(line);
|
||||
n += 1;
|
||||
}
|
||||
if n > 0 {
|
||||
println!("mirada-compositor · autoarranque: {n} programa(s) desde {}", path.display());
|
||||
}
|
||||
}
|
||||
|
||||
/// Carga las reglas de ventana del usuario, o ninguna si no hay archivo.
|
||||
fn load_user_rules() -> Rules {
|
||||
match Rules::default_path() {
|
||||
|
||||
Reference in New Issue
Block a user