atmos/kernel/
shortcut_manager.rs1#![allow(dead_code)]
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum InputAction {
6 Ignore,
7 TerminalInputChar(char),
8 TerminalHistoryUp,
9 TerminalHistoryDown,
10 SwitchTabRelative(isize),
11 NewTab,
12 CloseTab,
13 OpenFileDialog, SaveFile, TogglePowerMenu,
16 ToggleFocusSysmonTerminal,
17 BrowserScroll(i32),
18 DispatchToApp(u8, bool), Custom(u32),
20 AppCommand(u32), }
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
26pub enum ShortcutLayer {
27 OS = 1,
30 App = 2,
31 User = 3,
32}
33
34#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
36pub struct Modifiers {
37 pub ctrl: bool,
38 pub alt: bool,
39 pub shift: bool,
40}
41
42impl Modifiers {
43 pub fn new(ctrl: bool, alt: bool, shift: bool) -> Self {
44 Self { ctrl, alt, shift }
45 }
46}
47
48#[derive(Debug, Clone, PartialEq, Eq)]
50pub struct Shortcut {
51 pub keycode: u8,
52 pub modifiers: Modifiers,
53 pub layer: ShortcutLayer,
54 pub action: InputAction,
55 pub weight: usize, }
57
58impl Shortcut {
59 pub fn new(
60 keycode: u8,
61 modifiers: Modifiers,
62 layer: ShortcutLayer,
63 action: InputAction,
64 ) -> Self {
65 let mut mods = 0;
66 if modifiers.ctrl {
67 mods += 1;
68 }
69 if modifiers.alt {
70 mods += 1;
71 }
72 if modifiers.shift {
73 mods += 1;
74 }
75
76 Self {
77 keycode,
78 modifiers,
79 layer,
80 action,
81 weight: 1 + mods,
82 }
83 }
84}
85
86extern crate alloc;
87use alloc::vec::Vec;
88
89pub struct ShortcutManager {
90 shortcuts: Vec<Shortcut>,
91}
92
93impl Default for ShortcutManager {
94 fn default() -> Self {
95 Self::new()
96 }
97}
98
99impl ShortcutManager {
100 pub fn new() -> Self {
101 Self {
102 shortcuts: Vec::new(),
103 }
104 }
105
106 pub fn register(&mut self, shortcut: Shortcut) {
108 self.shortcuts.push(shortcut);
109 }
110
111 pub fn clear_app_shortcuts(&mut self) {
112 self.shortcuts.retain(|s| s.layer != ShortcutLayer::App);
113 }
114
115 pub fn clear_user_shortcuts(&mut self) {
116 self.shortcuts.retain(|s| s.layer != ShortcutLayer::User);
117 }
118
119 pub fn evaluate(&self, keycode: u8, modifiers: Modifiers) -> InputAction {
122 let mut matched = Vec::new();
124 for s in &self.shortcuts {
125 if s.keycode == keycode && s.modifiers == modifiers {
126 matched.push(s);
127 }
128 }
129
130 if matched.is_empty() {
133 return InputAction::Ignore;
134 }
135
136 matched.sort_by(|a, b| b.weight.cmp(&a.weight).then_with(|| b.layer.cmp(&a.layer)));
138
139 matched[0].action.clone()
140 }
141}
142