gioser

tawasuyu/brahman

Rust 476TOML 190Markdown 50JSON 176602 Definiciones

⎇ 3e2777540f992e839c6bbf93e21452062d183f66 crates/modules/mirada/mirada-brain/src/action.rs Rust · 95 líneas · 3.4 KB Historia Quién tocó qué crudo

feat(mirada): mirada-brain — orquestador de escritorio del compositor 3e2777540 · sergio ·

1//! Acciones de escritorio y su mapa de teclas por defecto.
2//!
3//! Una [`DesktopAction`] es una orden de alto nivel del usuario, ya
4//! desligada de la tecla concreta: el [`Desktop`](crate::Desktop) las
5//! aplica sin saber qué combinación las disparó.
6
7use mirada_layout::LayoutMode;
8
9/// Número de escritorios virtuales que mantiene el `Desktop`.
10pub const WORKSPACE_COUNT: usize = 9;
11
12/// Una orden de escritorio de alto nivel.
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum DesktopAction {
15    /// Mueve el foco a la ventana siguiente del escritorio activo.
16    FocusNext,
17    /// Mueve el foco a la ventana anterior.
18    FocusPrev,
19    /// Adelanta la ventana enfocada en el orden de teselado.
20    MoveForward,
21    /// Atrasa la ventana enfocada en el orden de teselado.
22    MoveBackward,
23    /// Cierra la ventana enfocada (cierre ordenado).
24    CloseFocused,
25    /// Pasa al siguiente modo de teselado.
26    CycleLayout,
27    /// Fija un modo de teselado concreto.
28    SetLayout(LayoutMode),
29    /// Activa el escritorio virtual `n` (índice 0-based).
30    SwitchWorkspace(usize),
31    /// Manda la ventana enfocada al escritorio virtual `n`.
32    SendToWorkspace(usize),
33    /// Apaga el compositor.
34    Quit,
35}
36
37/// Mapa de teclas por defecto, estilo *tiling WM* (modificador `Super`).
38///
39/// Las cadenas deben coincidir literalmente con las que el Cuerpo emite
40/// en [`BodyEvent::Keybind`](mirada_protocol::BodyEvent::Keybind); son
41/// también las que se registran con
42/// [`BrainCommand::GrabKeys`](mirada_protocol::BrainCommand::GrabKeys).
43pub fn default_keymap() -> Vec<(String, DesktopAction)> {
44    let mut map = vec![
45        ("Super+j".into(), DesktopAction::FocusNext),
46        ("Super+k".into(), DesktopAction::FocusPrev),
47        ("Super+Shift+j".into(), DesktopAction::MoveForward),
48        ("Super+Shift+k".into(), DesktopAction::MoveBackward),
49        ("Super+q".into(), DesktopAction::CloseFocused),
50        ("Super+space".into(), DesktopAction::CycleLayout),
51        ("Super+t".into(), DesktopAction::SetLayout(LayoutMode::MasterStack)),
52        ("Super+m".into(), DesktopAction::SetLayout(LayoutMode::Monocle)),
53        ("Super+g".into(), DesktopAction::SetLayout(LayoutMode::Grid)),
54        ("Super+c".into(), DesktopAction::SetLayout(LayoutMode::Columns)),
55        ("Super+Shift+e".into(), DesktopAction::Quit),
56    ];
57    // Un escritorio por dígito: `Super+1`..`Super+9` lo activan,
58    // `Super+Shift+1`.. mandan la ventana enfocada allí.
59    for n in 0..WORKSPACE_COUNT {
60        map.push((format!("Super+{}", n + 1), DesktopAction::SwitchWorkspace(n)));
61        map.push((
62            format!("Super+Shift+{}", n + 1),
63            DesktopAction::SendToWorkspace(n),
64        ));
65    }
66    map
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn keymap_has_no_duplicate_bindings() {
75        let map = default_keymap();
76        let mut keys: Vec<_> = map.iter().map(|(k, _)| k.clone()).collect();
77        keys.sort();
78        let unique = keys.len();
79        keys.dedup();
80        assert_eq!(keys.len(), unique, "hay un atajo repetido");
81    }
82
83    #[test]
84    fn keymap_covers_every_virtual_workspace() {
85        let map = default_keymap();
86        for n in 0..WORKSPACE_COUNT {
87            assert!(map
88                .iter()
89                .any(|(_, a)| *a == DesktopAction::SwitchWorkspace(n)));
90            assert!(map
91                .iter()
92                .any(|(_, a)| *a == DesktopAction::SendToWorkspace(n)));
93        }
94    }
95}