1use core::fmt::Debug;
2use core::marker::Copy;
3use core::marker::PhantomData;
4use core::ops::Index;
5
6use serde::Deserialize;
7
8use crate::input;
9use crate::key;
10use crate::keymap;
11
12#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
14pub struct Ref(pub u8);
15
16#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
18pub enum StickyKeyActivation {
19 OnStickyKeyRelease,
21 }
25
26#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
28pub enum StickyKeyRelease {
29 OnModifiedKeyRelease,
31 OnNextKeyPress,
33}
34
35#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
37pub struct Config {
38 #[serde(default = "default_activation")]
40 pub activation: StickyKeyActivation,
41 #[serde(default = "default_release")]
43 pub release: StickyKeyRelease,
44}
45
46pub const DEFAULT_ACTIVATION: StickyKeyActivation = StickyKeyActivation::OnStickyKeyRelease;
48
49pub const DEFAULT_RELEASE: StickyKeyRelease = StickyKeyRelease::OnModifiedKeyRelease;
51
52fn default_activation() -> StickyKeyActivation {
53 DEFAULT_ACTIVATION
54}
55
56fn default_release() -> StickyKeyRelease {
57 DEFAULT_RELEASE
58}
59
60pub const DEFAULT_CONFIG: Config = Config {
62 activation: DEFAULT_ACTIVATION,
63 release: DEFAULT_RELEASE,
64};
65
66impl Config {
67 pub const fn new() -> Self {
69 DEFAULT_CONFIG
70 }
71}
72
73impl Default for Config {
74 fn default() -> Self {
76 Self::new()
77 }
78}
79
80const MAX_STICKY_MODIFIERS: u8 = 4;
81
82struct ActiveModifiersDebugHelper<'a> {
83 active_modifiers: &'a [key::KeyboardModifiers; MAX_STICKY_MODIFIERS as usize],
84}
85
86impl core::fmt::Debug for ActiveModifiersDebugHelper<'_> {
87 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
88 let last_active_pos = self
90 .active_modifiers
91 .iter()
92 .rposition(|&pc| pc != key::KeyboardModifiers::NONE)
93 .map_or(0, |pos| pos + 1);
94 if last_active_pos < MAX_STICKY_MODIFIERS as usize {
95 f.debug_list()
96 .entries(&self.active_modifiers[..last_active_pos])
97 .finish_non_exhaustive()
98 } else {
99 f.debug_list().entries(&self.active_modifiers[..]).finish()
100 }
101 }
102}
103
104#[derive(Clone, Copy)]
106pub struct Context {
107 pub config: Config,
109 pub active_modifiers: [key::KeyboardModifiers; MAX_STICKY_MODIFIERS as usize],
111 pub active_modifier_count: u8,
113 pub pressed_keymap_index: Option<u16>,
115}
116
117impl core::fmt::Debug for Context {
118 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
119 f.debug_struct("Context")
120 .field("config", &self.config)
121 .field(
122 "active_modifiers",
123 &ActiveModifiersDebugHelper {
124 active_modifiers: &self.active_modifiers,
125 },
126 )
127 .field("active_modifier_count", &self.active_modifier_count)
128 .field("pressed_keymap_index", &self.pressed_keymap_index)
129 .finish()
130 }
131}
132
133impl Context {
134 pub const fn from_config(config: Config) -> Context {
136 Context {
137 config,
138 active_modifiers: [key::KeyboardModifiers::NONE; MAX_STICKY_MODIFIERS as usize],
139 active_modifier_count: 0,
140 pressed_keymap_index: None,
141 }
142 }
143
144 fn handle_event(&mut self, event: key::Event<Event>) -> key::KeyEvents<Event> {
146 match (self.active_modifier_count, event) {
173 (
176 0,
177 key::Event::Key {
178 key_event: Event::ActivateModifiers(mods),
179 ..
180 },
181 ) => {
182 self.active_modifiers[0] = mods;
183 self.active_modifier_count = 1;
184
185 key::KeyEvents::no_events()
186 }
187 (
190 active_modifier_count,
191 key::Event::Key {
192 key_event: Event::ActivateModifiers(mods),
193 ..
194 },
195 ) => {
196 if active_modifier_count < MAX_STICKY_MODIFIERS {
197 self.active_modifiers[active_modifier_count as usize] = mods;
198 self.active_modifier_count += 1;
199 }
200
201 key::KeyEvents::no_events()
202 }
203 (
207 active_modifier_count,
208 key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput { keymap_index, .. }),
209 ) if active_modifier_count > 0 => {
210 let pke = key::KeyEvents::no_events();
211
212 self.pressed_keymap_index = Some(keymap_index);
217
218 pke
223 }
224 (
227 active_modifier_count,
228 key::Event::Input(input::Event::Release {
229 keymap_index: ev_kmi,
230 }),
231 ) if Some(ev_kmi) == self.pressed_keymap_index && active_modifier_count > 0 => {
232 let mut pke = key::KeyEvents::no_events();
234
235 self.active_modifiers[..active_modifier_count as usize]
236 .iter()
237 .for_each(|&m| {
238 let sticky_key_output = key::KeyOutput::from_key_modifiers(m);
239 let vk_ev = key::Event::Input(input::Event::VirtualKeyRelease {
240 key_output: sticky_key_output,
241 });
242 pke.add_event(key::ScheduledEvent::immediate(vk_ev));
243 });
244
245 self.active_modifier_count = 0;
246 self.pressed_keymap_index = None;
247
248 pke
249 }
250 (active_modifier_count, key::Event::Input(input::Event::Press { .. }))
255 if self.pressed_keymap_index.is_some()
256 && self.config.release == StickyKeyRelease::OnNextKeyPress =>
257 {
258 let mut pke = key::KeyEvents::no_events();
261
262 self.active_modifiers[..active_modifier_count as usize]
263 .iter()
264 .for_each(|&m| {
265 let sticky_key_output = key::KeyOutput::from_key_modifiers(m);
266 let vk_ev = key::Event::Input(input::Event::VirtualKeyRelease {
267 key_output: sticky_key_output,
268 });
269 pke.add_event(key::ScheduledEvent::immediate(vk_ev));
270 });
271
272 self.active_modifier_count = 0;
273 self.pressed_keymap_index = None;
274
275 pke
276 }
277 _ => key::KeyEvents::no_events(),
278 }
279 }
280}
281
282impl key::Context for Context {
283 type Event = Event;
284
285 fn handle_event(&mut self, event: key::Event<Self::Event>) -> key::KeyEvents<Self::Event> {
286 self.handle_event(event)
287 }
288}
289
290#[derive(Debug, Clone, Copy, PartialEq)]
292pub enum Event {
293 ActivateModifiers(key::KeyboardModifiers),
295}
296
297#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
299pub struct Key {
300 pub sticky_modifiers: key::KeyboardModifiers,
302}
303
304impl Key {
305 pub const fn new(sticky_modifiers: key::KeyboardModifiers) -> Self {
307 Key { sticky_modifiers }
308 }
309
310 pub fn new_pressed_key(&self) -> KeyState {
312 KeyState::new()
313 }
314}
315
316#[derive(Debug, Clone, Copy, PartialEq)]
318pub struct PendingKeyState;
319
320#[derive(Debug, Clone, Copy, Eq, PartialEq)]
322pub enum Behavior {
323 Sticky,
325 Regular,
327}
328
329#[derive(Debug, Clone, Copy, PartialEq)]
331pub struct KeyState {
332 behavior: Behavior,
333}
334
335impl KeyState {
336 pub fn new() -> Self {
338 KeyState {
339 behavior: Behavior::Sticky,
340 }
341 }
342}
343
344impl Default for KeyState {
345 fn default() -> Self {
347 Self::new()
348 }
349}
350
351impl KeyState {
352 pub fn update_state(
354 &mut self,
355 key: &Key,
356 context: &Context,
357 keymap_index: u16,
358 event: key::Event<Event>,
359 ) -> key::KeyEvents<Event> {
360 match self.behavior {
365 Behavior::Sticky => match event {
366 key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput { .. }) => {
367 self.behavior = Behavior::Regular;
370
371 key::KeyEvents::no_events()
372 }
373 key::Event::Input(input::Event::Release {
374 keymap_index: released_index,
375 }) if released_index == keymap_index => {
376 match context.config.activation {
378 StickyKeyActivation::OnStickyKeyRelease => {
379 let sticky_ev = Event::ActivateModifiers(key.sticky_modifiers);
380 let k_ev = key::Event::key_event(keymap_index, sticky_ev);
381
382 let sticky_key_output =
383 key::KeyOutput::from_key_modifiers(key.sticky_modifiers);
384 let vk_ev = key::Event::Input(input::Event::VirtualKeyPress {
385 key_output: sticky_key_output,
386 });
387
388 let mut pke = key::KeyEvents::event(k_ev);
389 pke.add_event(key::ScheduledEvent::immediate(vk_ev));
390 pke
391 }
392 }
393 }
394 _ => key::KeyEvents::no_events(),
395 },
396 Behavior::Regular => key::KeyEvents::no_events(),
397 }
398 }
399
400 pub fn key_output(&self, key: &Key) -> Option<key::KeyOutput> {
402 match self.behavior {
403 Behavior::Sticky => None,
404 Behavior::Regular => Some(key::KeyOutput::from_key_modifiers(key.sticky_modifiers)),
405 }
406 }
407}
408
409#[derive(Debug, Clone, Copy, PartialEq)]
411pub struct System<R, Keys: Index<usize, Output = Key>> {
412 keys: Keys,
413 marker: PhantomData<R>,
414}
415
416impl<R, Keys: Index<usize, Output = Key>> System<R, Keys> {
417 pub const fn new(keys: Keys) -> Self {
419 Self {
420 keys,
421 marker: PhantomData,
422 }
423 }
424}
425
426impl<R: Debug, Keys: Debug + Index<usize, Output = Key>> key::System<R> for System<R, Keys> {
427 type Ref = Ref;
428 type Context = Context;
429 type Event = Event;
430 type PendingKeyState = PendingKeyState;
431 type KeyState = KeyState;
432
433 fn new_pressed_key(
434 &self,
435 _keymap_index: u16,
436 _context: &Self::Context,
437 Ref(key_index): Ref,
438 ) -> (
439 key::PressedKeyResult<R, Self::PendingKeyState, Self::KeyState>,
440 key::KeyEvents<Self::Event>,
441 ) {
442 let key = &self.keys[key_index as usize];
443 let ks = key.new_pressed_key();
444 let pks = key::PressedKeyResult::Resolved(ks);
445 let pke = key::KeyEvents::no_events();
446 (pks, pke)
447 }
448
449 fn update_pending_state(
450 &self,
451 _pending_state: &mut Self::PendingKeyState,
452 _keymap_index: u16,
453 _context: &Self::Context,
454 _key_ref: Ref,
455 _event: key::Event<Self::Event>,
456 ) -> (Option<key::NewPressedKey<R>>, key::KeyEvents<Self::Event>) {
457 panic!()
458 }
459
460 fn update_state(
461 &self,
462 key_state: &mut Self::KeyState,
463 Ref(key_index): &Self::Ref,
464 context: &Self::Context,
465 keymap_index: u16,
466 event: key::Event<Self::Event>,
467 ) -> key::KeyEvents<Self::Event> {
468 let key = &self.keys[*key_index as usize];
469 key_state.update_state(key, context, keymap_index, event)
470 }
471
472 fn key_output(
473 &self,
474 Ref(key_index): &Self::Ref,
475 key_state: &Self::KeyState,
476 ) -> Option<key::KeyOutput> {
477 let key = &self.keys[*key_index as usize];
478 key_state.key_output(key)
479 }
480}
481
482#[cfg(test)]
483mod tests {
484 use super::*;
485
486 #[test]
487 fn test_sizeof_ref() {
488 assert_eq!(1, core::mem::size_of::<Ref>());
489 }
490
491 #[test]
492 fn test_sizeof_event() {
493 assert_eq!(1, core::mem::size_of::<Event>());
494 }
495}