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:
@@ -40,6 +40,8 @@ pub enum DesktopAction {
|
||||
CloseFocused,
|
||||
/// Alterna entre flotante y teselada la ventana enfocada.
|
||||
ToggleFloat,
|
||||
/// Alterna pantalla completa en la ventana enfocada.
|
||||
ToggleFullscreen,
|
||||
/// Pasa al siguiente modo de teselado.
|
||||
CycleLayout,
|
||||
/// Fija un modo de teselado concreto.
|
||||
@@ -101,6 +103,7 @@ impl fmt::Display for DesktopAction {
|
||||
DesktopAction::MoveBackward => f.write_str("move-backward"),
|
||||
DesktopAction::CloseFocused => f.write_str("close-focused"),
|
||||
DesktopAction::ToggleFloat => f.write_str("toggle-float"),
|
||||
DesktopAction::ToggleFullscreen => f.write_str("toggle-fullscreen"),
|
||||
DesktopAction::CycleLayout => f.write_str("cycle-layout"),
|
||||
DesktopAction::SetLayout(m) => write!(f, "layout:{}", layout_slug(*m)),
|
||||
DesktopAction::GrowMaster => f.write_str("grow-master"),
|
||||
@@ -129,6 +132,7 @@ impl FromStr for DesktopAction {
|
||||
"move-backward" => Self::MoveBackward,
|
||||
"close-focused" => Self::CloseFocused,
|
||||
"toggle-float" => Self::ToggleFloat,
|
||||
"toggle-fullscreen" => Self::ToggleFullscreen,
|
||||
"cycle-layout" => Self::CycleLayout,
|
||||
"grow-master" => Self::GrowMaster,
|
||||
"shrink-master" => Self::ShrinkMaster,
|
||||
@@ -188,6 +192,7 @@ pub fn default_keymap() -> Vec<(String, DesktopAction)> {
|
||||
("Super+Shift+k".into(), DesktopAction::MoveBackward),
|
||||
("Super+q".into(), DesktopAction::CloseFocused),
|
||||
("Super+f".into(), DesktopAction::ToggleFloat),
|
||||
("Super+Shift+f".into(), DesktopAction::ToggleFullscreen),
|
||||
("Super+space".into(), DesktopAction::CycleLayout),
|
||||
("Super+t".into(), DesktopAction::SetLayout(LayoutMode::MasterStack)),
|
||||
("Super+m".into(), DesktopAction::SetLayout(LayoutMode::Monocle)),
|
||||
|
||||
@@ -218,6 +218,18 @@ impl Desktop {
|
||||
}
|
||||
self.relayout()
|
||||
}
|
||||
DesktopAction::ToggleFullscreen => {
|
||||
let Some(id) = self.workspaces[self.active].focused() else {
|
||||
return Vec::new();
|
||||
};
|
||||
let ws = &mut self.workspaces[self.active];
|
||||
if ws.fullscreen() == Some(id) {
|
||||
ws.set_fullscreen(None);
|
||||
} else {
|
||||
ws.set_fullscreen(Some(id));
|
||||
}
|
||||
self.relayout()
|
||||
}
|
||||
DesktopAction::CycleLayout => {
|
||||
let next = self.workspaces[self.active].params().mode.next();
|
||||
self.workspaces[self.active].set_mode(next);
|
||||
@@ -475,6 +487,23 @@ mod tests {
|
||||
assert!(!places(&cmds).iter().find(|x| x.id == 2).unwrap().floating);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn toggle_fullscreen_covers_the_screen_and_hides_the_rest() {
|
||||
let mut d = desktop_with_screen();
|
||||
for id in [1, 2, 3] {
|
||||
open(&mut d, id);
|
||||
}
|
||||
let cmds = d.apply(DesktopAction::ToggleFullscreen); // sobre la 3
|
||||
let p = places(&cmds);
|
||||
let fs = p.iter().find(|x| x.id == 3).unwrap();
|
||||
assert!(fs.fullscreen && fs.visible);
|
||||
assert_eq!(fs.rect, d.screen().unwrap());
|
||||
assert!(p.iter().filter(|x| x.id != 3).all(|x| !x.visible));
|
||||
// Alternar de nuevo restaura el teselado: las tres visibles.
|
||||
let cmds = d.apply(DesktopAction::ToggleFullscreen);
|
||||
assert_eq!(places(&cmds).iter().filter(|x| x.visible).count(), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_rule_sends_a_new_window_to_its_workspace() {
|
||||
let mut d = desktop_with_screen();
|
||||
|
||||
@@ -238,6 +238,7 @@ const KEYMAP_HEADER: &str = "\
|
||||
// move-forward / move-backward reordena la ventana enfocada
|
||||
// close-focused cierra la enfocada
|
||||
// toggle-float alterna flotante / teselada
|
||||
// toggle-fullscreen alterna pantalla completa
|
||||
// cycle-layout siguiente modo de teselado
|
||||
// layout:<modo> master-stack | centered-master | spiral
|
||||
// grid | columns | rows | monocle
|
||||
|
||||
Reference in New Issue
Block a user