feat(mirada): nmaster, promover a maestra y smart gaps (estilo dwm)
Tanda de funciones de tiling WM, toda pura (mirada-layout/brain), sin tocar el protocolo: - nmaster: LayoutParams.master_count — cuántas ventanas van en el área maestra. MasterStack y CenteredMaster apilan N maestras; sin pila, las maestras llenan la pantalla. Acciones inc-master/dec-master (Super+, Super+.), acotadas 1..9. - Promover a maestra: Workspace::promote_focused lleva la ventana enfocada al puesto 0. Acción promote-to-master (Super+Return). - Smart gaps: una sola ventana se tesela a sangre, sin margen. combo_string del compositor canoniza ahora teclas con nombre (Return, Tab, F5, flechas…) vía xkb::keysym_get_name, no sólo caracteres imprimibles — sin eso Super+Return no sería un atajo expresable. Cableado en keymap por defecto, HUD de mirada y mirada-ctl. Verificado end-to-end con headless-ctl. mirada-layout 26->30, mirada-brain 39->41. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -46,6 +46,12 @@ pub enum DesktopAction {
|
||||
GrowMaster,
|
||||
/// Encoge el área de la ventana maestra.
|
||||
ShrinkMaster,
|
||||
/// Mete una ventana más en el área maestra (`nmaster`).
|
||||
IncMaster,
|
||||
/// Saca una ventana del área maestra.
|
||||
DecMaster,
|
||||
/// Lleva la ventana enfocada al puesto maestro (orden de teselado).
|
||||
PromoteToMaster,
|
||||
/// Activa el escritorio virtual `n` (índice 0-based).
|
||||
SwitchWorkspace(usize),
|
||||
/// Manda la ventana enfocada al escritorio virtual `n`.
|
||||
@@ -96,6 +102,9 @@ impl fmt::Display for DesktopAction {
|
||||
DesktopAction::SetLayout(m) => write!(f, "layout:{}", layout_slug(*m)),
|
||||
DesktopAction::GrowMaster => f.write_str("grow-master"),
|
||||
DesktopAction::ShrinkMaster => f.write_str("shrink-master"),
|
||||
DesktopAction::IncMaster => f.write_str("inc-master"),
|
||||
DesktopAction::DecMaster => f.write_str("dec-master"),
|
||||
DesktopAction::PromoteToMaster => f.write_str("promote-to-master"),
|
||||
// Los escritorios se numeran 1-based de cara al usuario.
|
||||
DesktopAction::SwitchWorkspace(n) => write!(f, "workspace:{}", n + 1),
|
||||
DesktopAction::SendToWorkspace(n) => write!(f, "send-to-workspace:{}", n + 1),
|
||||
@@ -119,6 +128,9 @@ impl FromStr for DesktopAction {
|
||||
"cycle-layout" => Self::CycleLayout,
|
||||
"grow-master" => Self::GrowMaster,
|
||||
"shrink-master" => Self::ShrinkMaster,
|
||||
"inc-master" => Self::IncMaster,
|
||||
"dec-master" => Self::DecMaster,
|
||||
"promote-to-master" => Self::PromoteToMaster,
|
||||
"quit" => Self::Quit,
|
||||
_ => {
|
||||
if let Some(slug) = s.strip_prefix("layout:") {
|
||||
@@ -181,6 +193,9 @@ pub fn default_keymap() -> Vec<(String, DesktopAction)> {
|
||||
("Super+s".into(), DesktopAction::SetLayout(LayoutMode::Spiral)),
|
||||
("Super+h".into(), DesktopAction::ShrinkMaster),
|
||||
("Super+l".into(), DesktopAction::GrowMaster),
|
||||
("Super+Return".into(), DesktopAction::PromoteToMaster),
|
||||
("Super+,".into(), DesktopAction::IncMaster),
|
||||
("Super+.".into(), DesktopAction::DecMaster),
|
||||
("Super+Shift+e".into(), DesktopAction::Quit),
|
||||
];
|
||||
// Un escritorio por dígito: `Super+1`..`Super+9` lo activan,
|
||||
|
||||
@@ -190,6 +190,12 @@ impl Desktop {
|
||||
}
|
||||
DesktopAction::GrowMaster => self.nudge_master(0.05),
|
||||
DesktopAction::ShrinkMaster => self.nudge_master(-0.05),
|
||||
DesktopAction::IncMaster => self.nudge_master_count(1),
|
||||
DesktopAction::DecMaster => self.nudge_master_count(-1),
|
||||
DesktopAction::PromoteToMaster => {
|
||||
self.workspaces[self.active].promote_focused();
|
||||
self.relayout()
|
||||
}
|
||||
DesktopAction::SwitchWorkspace(n) => {
|
||||
if n < self.workspaces.len() && n != self.active {
|
||||
self.active = n;
|
||||
@@ -224,6 +230,14 @@ impl Desktop {
|
||||
self.relayout()
|
||||
}
|
||||
|
||||
/// Ajusta `nmaster` del escritorio activo, acotado a `1..=9`.
|
||||
fn nudge_master_count(&mut self, delta: i32) -> Vec<BrainCommand> {
|
||||
let ws = &mut self.workspaces[self.active];
|
||||
let n = (ws.params().master_count as i32 + delta).clamp(1, 9) as usize;
|
||||
ws.set_master_count(n);
|
||||
self.relayout()
|
||||
}
|
||||
|
||||
/// Recalcula la geometría del escritorio activo y la empaqueta en un
|
||||
/// [`BrainCommand::Place`]. Sin salida conectada, no hay nada que
|
||||
/// colocar.
|
||||
@@ -468,6 +482,32 @@ mod tests {
|
||||
assert!((d.active_workspace().params().master_ratio - r0).abs() < 1e-6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inc_and_dec_master_adjust_nmaster() {
|
||||
let mut d = desktop_with_screen();
|
||||
for id in [1, 2, 3] {
|
||||
open(&mut d, id);
|
||||
}
|
||||
assert_eq!(d.active_workspace().params().master_count, 1);
|
||||
d.apply(DesktopAction::IncMaster);
|
||||
assert_eq!(d.active_workspace().params().master_count, 2);
|
||||
d.apply(DesktopAction::DecMaster);
|
||||
d.apply(DesktopAction::DecMaster); // no baja de 1
|
||||
assert_eq!(d.active_workspace().params().master_count, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn promote_to_master_brings_the_focused_window_to_the_front() {
|
||||
let mut d = desktop_with_screen();
|
||||
for id in [1, 2, 3] {
|
||||
open(&mut d, id);
|
||||
}
|
||||
d.apply(DesktopAction::FocusWindow(3));
|
||||
d.apply(DesktopAction::PromoteToMaster);
|
||||
assert_eq!(d.active_workspace().windows()[0], 3);
|
||||
assert_eq!(d.focused_window(), Some(3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn master_ratio_stays_within_bounds() {
|
||||
let mut d = desktop_with_screen();
|
||||
|
||||
@@ -241,6 +241,8 @@ const KEYMAP_HEADER: &str = "\
|
||||
// layout:<modo> master-stack | centered-master | spiral
|
||||
// grid | columns | rows | monocle
|
||||
// grow-master / shrink-master redimensiona el área maestra
|
||||
// inc-master / dec-master nº de ventanas maestras (nmaster)
|
||||
// promote-to-master la enfocada al puesto maestro
|
||||
// workspace:N activa el escritorio N (1..9)
|
||||
// send-to-workspace:N manda la enfocada al escritorio N
|
||||
// quit apaga el compositor
|
||||
|
||||
Reference in New Issue
Block a user