1use core::fmt::Debug;
2use core::marker::Copy;
3
4use serde::Deserialize;
5
6use crate::input;
7use crate::key;
8use crate::keymap;
9
10#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
12pub enum StickyKeyActivation {
13 OnStickyKeyRelease,
15 }
19
20#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
22pub enum StickyKeyRelease {
23 OnModifiedKeyRelease,
25 OnNextKeyPress,
27}
28
29#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
31pub struct Config {
32 #[serde(default = "default_activation")]
34 pub activation: StickyKeyActivation,
35 #[serde(default = "default_release")]
37 pub release: StickyKeyRelease,
38}
39
40fn default_activation() -> StickyKeyActivation {
41 DEFAULT_CONFIG.activation
42}
43
44fn default_release() -> StickyKeyRelease {
45 DEFAULT_CONFIG.release
46}
47
48pub const DEFAULT_CONFIG: Config = Config {
50 activation: StickyKeyActivation::OnStickyKeyRelease,
51 release: StickyKeyRelease::OnModifiedKeyRelease,
52};
53
54impl Default for Config {
55 fn default() -> Self {
57 DEFAULT_CONFIG
58 }
59}
60
61const MAX_STICKY_MODIFIERS: u8 = 4;
62
63#[derive(Debug, Clone, Copy)]
65pub struct Context {
66 pub config: Config,
68 pub active_modifiers: [key::KeyboardModifiers; MAX_STICKY_MODIFIERS as usize],
70 pub active_modifier_count: u8,
72 pub pressed_keymap_index: Option<u16>,
74}
75
76pub const DEFAULT_CONTEXT: Context = Context {
78 config: DEFAULT_CONFIG,
79 active_modifiers: [key::KeyboardModifiers::NONE; MAX_STICKY_MODIFIERS as usize],
80 active_modifier_count: 0,
81 pressed_keymap_index: None,
82};
83
84impl Context {
85 pub const fn from_config(config: Config) -> Context {
87 Context {
88 config,
89 ..DEFAULT_CONTEXT
90 }
91 }
92
93 pub fn handle_event(&mut self, event: key::Event<Event>) -> key::KeyEvents<Event> {
95 match (self.active_modifier_count, event) {
122 (
125 0,
126 key::Event::Key {
127 key_event: Event::ActivateModifiers(mods),
128 ..
129 },
130 ) => {
131 self.active_modifiers[0] = mods;
132 self.active_modifier_count = 1;
133
134 key::KeyEvents::no_events()
135 }
136 (
139 active_modifier_count,
140 key::Event::Key {
141 key_event: Event::ActivateModifiers(mods),
142 ..
143 },
144 ) => {
145 if active_modifier_count < MAX_STICKY_MODIFIERS {
146 self.active_modifiers[active_modifier_count as usize] = mods;
147 self.active_modifier_count += 1;
148 }
149
150 key::KeyEvents::no_events()
151 }
152 (
156 active_modifier_count,
157 key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput { keymap_index, .. }),
158 ) if active_modifier_count > 0 => {
159 let pke = key::KeyEvents::no_events();
160
161 self.pressed_keymap_index = Some(keymap_index);
166
167 pke
172 }
173 (
176 active_modifier_count,
177 key::Event::Input(input::Event::Release {
178 keymap_index: ev_kmi,
179 }),
180 ) if Some(ev_kmi) == self.pressed_keymap_index && active_modifier_count > 0 => {
181 let mut pke = key::KeyEvents::no_events();
183
184 self.active_modifiers[..active_modifier_count as usize]
185 .iter()
186 .for_each(|&m| {
187 let sticky_key_output = key::KeyOutput::from_key_modifiers(m);
188 let vk_ev = key::Event::Input(input::Event::VirtualKeyRelease {
189 key_output: sticky_key_output,
190 });
191 pke.add_event(key::ScheduledEvent::immediate(vk_ev));
192 });
193
194 self.active_modifier_count = 0;
195 self.pressed_keymap_index = None;
196
197 pke
198 }
199 (active_modifier_count, key::Event::Input(input::Event::Press { .. }))
204 if self.pressed_keymap_index.is_some()
205 && self.config.release == StickyKeyRelease::OnNextKeyPress =>
206 {
207 let mut pke = key::KeyEvents::no_events();
210
211 self.active_modifiers[..active_modifier_count as usize]
212 .iter()
213 .for_each(|&m| {
214 let sticky_key_output = key::KeyOutput::from_key_modifiers(m);
215 let vk_ev = key::Event::Input(input::Event::VirtualKeyRelease {
216 key_output: sticky_key_output,
217 });
218 pke.add_event(key::ScheduledEvent::immediate(vk_ev));
219 });
220
221 self.active_modifier_count = 0;
222 self.pressed_keymap_index = None;
223
224 pke
225 }
226 _ => key::KeyEvents::no_events(),
227 }
228 }
229}
230
231#[derive(Debug, Clone, Copy, PartialEq)]
233pub enum Event {
234 ActivateModifiers(key::KeyboardModifiers),
236}
237
238#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
240pub struct Key {
241 pub sticky_modifiers: key::KeyboardModifiers,
243}
244
245impl Key {
246 pub const fn new(sticky_modifiers: key::KeyboardModifiers) -> Self {
248 Key { sticky_modifiers }
249 }
250
251 pub fn new_pressed_key(&self) -> KeyState {
253 KeyState::new(self.sticky_modifiers)
254 }
255}
256
257impl key::Key for Key {
258 type Context = crate::init::Context;
259 type Event = crate::init::Event;
260 type PendingKeyState = crate::init::PendingKeyState;
261 type KeyState = crate::init::KeyState;
262
263 fn new_pressed_key(
264 &self,
265 _context: &Self::Context,
266 _key_path: key::KeyPath,
267 ) -> (
268 key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>,
269 key::KeyEvents<Self::Event>,
270 ) {
271 let ks = self.new_pressed_key();
272 let pks = key::PressedKeyResult::Resolved(ks.into());
273 let pke = key::KeyEvents::no_events();
274 (pks, pke)
275 }
276
277 fn handle_event(
278 &self,
279 _pending_state: &mut Self::PendingKeyState,
280 _context: &Self::Context,
281 _key_path: key::KeyPath,
282 _event: key::Event<Self::Event>,
283 ) -> (Option<key::NewPressedKey>, key::KeyEvents<Self::Event>) {
284 panic!()
285 }
286
287 fn lookup(
288 &self,
289 _path: &[u16],
290 ) -> &dyn key::Key<
291 Context = Self::Context,
292 Event = Self::Event,
293 PendingKeyState = Self::PendingKeyState,
294 KeyState = Self::KeyState,
295 > {
296 self
297 }
298}
299
300#[derive(Debug, Clone, Copy, Eq, PartialEq)]
302pub enum Behavior {
303 Sticky,
305 Regular,
307}
308
309#[derive(Debug, Clone, Copy, PartialEq)]
311pub struct KeyState {
312 sticky_modifiers: key::KeyboardModifiers,
313 behavior: Behavior,
314}
315
316impl KeyState {
317 pub fn new(sticky_modifiers: key::KeyboardModifiers) -> Self {
319 KeyState {
320 sticky_modifiers,
321 behavior: Behavior::Sticky,
322 }
323 }
324}
325
326impl KeyState {
327 pub fn handle_event(
329 &mut self,
330 context: &Context,
331 keymap_index: u16,
332 event: key::Event<Event>,
333 ) -> key::KeyEvents<Event> {
334 match self.behavior {
339 Behavior::Sticky => match event {
340 key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput { .. }) => {
341 self.behavior = Behavior::Regular;
344
345 key::KeyEvents::no_events()
346 }
347 key::Event::Input(input::Event::Release {
348 keymap_index: released_index,
349 }) if released_index == keymap_index => {
350 match context.config.activation {
352 StickyKeyActivation::OnStickyKeyRelease => {
353 let sticky_ev = Event::ActivateModifiers(self.sticky_modifiers);
354 let k_ev = key::Event::key_event(keymap_index, sticky_ev);
355
356 let sticky_key_output =
357 key::KeyOutput::from_key_modifiers(self.sticky_modifiers);
358 let vk_ev = key::Event::Input(input::Event::VirtualKeyPress {
359 key_output: sticky_key_output,
360 });
361
362 let mut pke = key::KeyEvents::event(k_ev);
363 pke.add_event(key::ScheduledEvent::immediate(vk_ev));
364 pke
365 }
366 }
367 }
368 _ => key::KeyEvents::no_events(),
369 },
370 Behavior::Regular => key::KeyEvents::no_events(),
371 }
372 }
373
374 pub fn key_output(&self) -> Option<key::KeyOutput> {
376 match self.behavior {
377 Behavior::Sticky => None,
378 Behavior::Regular => Some(key::KeyOutput::from_key_modifiers(self.sticky_modifiers)),
379 }
380 }
381}