feat(mirada): pantalla completa real — toggle-fullscreen

ToggleFullscreen (Super+Shift+f) lleva la ventana enfocada a pantalla
completa: cubre toda la salida sin gap, oculta al resto y se lleva el
foco. Distinto del modo Monocle (un modo de teselado): es un estado
por ventana que ignora el layout.

- Workspace.fullscreen: Option<WindowId>; set_fullscreen / fullscreen();
  remove() lo limpia si se cierra esa ventana.
- placements() da a la fullscreen el rect completo y marca al resto
  visible: false. WindowPlacement y BodyOp::Configure llevan
  fullscreen: bool.
- mirada-compositor fija el estado xdg_toplevel::Fullscreen en la
  superficie, para que el cliente lo sepa.
- Cableado en keymap, HUD de mirada y mirada-ctl.

Verificado end-to-end con headless-ctl. mirada-protocol 10->11,
mirada-brain 51->52.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
sergio
2026-05-21 01:07:01 +00:00
parent 6dfd9e62ac
commit be61ddb6eb
12 changed files with 133 additions and 11 deletions
+6 -1
View File
@@ -174,13 +174,18 @@ impl App {
/// Ejecuta una operación concreta sobre las superficies reales.
fn exec_op(&mut self, op: BodyOp) {
match op {
BodyOp::Configure { id, rect, visible, floating } => {
BodyOp::Configure { id, rect, visible, floating, fullscreen } => {
if let Some(w) = self.windows.iter_mut().find(|w| w.id == id) {
w.loc = (rect.x, rect.y);
w.visible = visible;
w.floating = floating;
w.toplevel.with_pending_state(|s| {
s.size = Some((rect.w.max(1), rect.h.max(1)).into());
if fullscreen {
s.states.set(xdg_toplevel::State::Fullscreen);
} else {
s.states.unset(xdg_toplevel::State::Fullscreen);
}
});
w.toplevel.send_pending_configure();
}
+1
View File
@@ -121,6 +121,7 @@ Acciones de mirada-ctl:
move-backward la atrasa
close-focused cierra la ventana enfocada
toggle-float alterna flotante / teselada la enfocada
toggle-fullscreen alterna pantalla completa en la enfocada
cycle-layout pasa al siguiente modo de teselado
layout <modo> master-stack · centered-master · spiral
grid · columns · rows · monocle
+5 -2
View File
@@ -21,7 +21,7 @@
//! ```text
//! n abre una ventana tab / espacio cicla layout
//! w cierra la enfocada t m g c r d s layout directo
//! f flota / tesela h / l área maestra /+
//! f / Shift+f flota / pantalla completa h / l área maestra /+
//! j / k foco siguiente/anterior , / . nmaster /+
//! Shift+j / k mueve la enfocada 1..9 ir a escritorio
//! Enter promueve a maestra Ctrl+1..9 enviar a escritorio
@@ -283,6 +283,7 @@ impl Mirada {
match ks.key.as_str() {
"n" if !connected => self.open_window(),
"w" => self.act(DesktopAction::CloseFocused),
"f" if shift => self.act(DesktopAction::ToggleFullscreen),
"f" => self.act(DesktopAction::ToggleFloat),
"j" if shift => self.act(DesktopAction::MoveForward),
"k" if shift => self.act(DesktopAction::MoveBackward),
@@ -454,7 +455,9 @@ impl Render for Mirada {
let tb_bg = if p.focused { theme.accent } else { theme.bg_row_hover };
let tb_fg = if p.focused { on_accent } else { theme.fg_muted };
let pid = p.id;
let kind_label = if p.floating {
let kind_label = if p.fullscreen {
"· pantalla completa ·"
} else if p.floating {
"· ventana flotante ·"
} else {
"· superficie del Cuerpo ·"