1use core::fmt::Debug;
2use core::marker::Copy;
3use core::ops::Index;
4
5use serde::Deserialize;
6
7use crate::input;
8use crate::key;
9use crate::keymap;
10
11#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
13pub struct Ref(pub u8);
14
15#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
17pub enum StickyKeyActivation {
18 OnStickyKeyRelease,
20 }
24
25#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
27pub enum StickyKeyRelease {
28 OnModifiedKeyRelease,
30 OnNextKeyPress,
32}
33
34#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
36pub struct Config {
37 #[serde(default = "default_activation")]
39 pub activation: StickyKeyActivation,
40 #[serde(default = "default_release")]
42 pub release: StickyKeyRelease,
43}
44
45fn default_activation() -> StickyKeyActivation {
46 DEFAULT_CONFIG.activation
47}
48
49fn default_release() -> StickyKeyRelease {
50 DEFAULT_CONFIG.release
51}
52
53pub const DEFAULT_CONFIG: Config = Config {
55 activation: StickyKeyActivation::OnStickyKeyRelease,
56 release: StickyKeyRelease::OnModifiedKeyRelease,
57};
58
59impl Default for Config {
60 fn default() -> Self {
62 DEFAULT_CONFIG
63 }
64}
65
66const MAX_STICKY_MODIFIERS: u8 = 4;
67
68#[derive(Debug, Clone, Copy)]
70pub struct Context {
71 pub config: Config,
73 pub active_modifiers: [key::KeyboardModifiers; MAX_STICKY_MODIFIERS as usize],
75 pub active_modifier_count: u8,
77 pub pressed_keymap_index: Option<u16>,
79}
80
81pub const DEFAULT_CONTEXT: Context = Context {
83 config: DEFAULT_CONFIG,
84 active_modifiers: [key::KeyboardModifiers::NONE; MAX_STICKY_MODIFIERS as usize],
85 active_modifier_count: 0,
86 pressed_keymap_index: None,
87};
88
89impl Context {
90 pub const fn from_config(config: Config) -> Context {
92 Context {
93 config,
94 ..DEFAULT_CONTEXT
95 }
96 }
97
98 pub fn handle_event(&mut self, event: key::Event<Event>) -> key::KeyEvents<Event> {
100 match (self.active_modifier_count, event) {
127 (
130 0,
131 key::Event::Key {
132 key_event: Event::ActivateModifiers(mods),
133 ..
134 },
135 ) => {
136 self.active_modifiers[0] = mods;
137 self.active_modifier_count = 1;
138
139 key::KeyEvents::no_events()
140 }
141 (
144 active_modifier_count,
145 key::Event::Key {
146 key_event: Event::ActivateModifiers(mods),
147 ..
148 },
149 ) => {
150 if active_modifier_count < MAX_STICKY_MODIFIERS {
151 self.active_modifiers[active_modifier_count as usize] = mods;
152 self.active_modifier_count += 1;
153 }
154
155 key::KeyEvents::no_events()
156 }
157 (
161 active_modifier_count,
162 key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput { keymap_index, .. }),
163 ) if active_modifier_count > 0 => {
164 let pke = key::KeyEvents::no_events();
165
166 self.pressed_keymap_index = Some(keymap_index);
171
172 pke
177 }
178 (
181 active_modifier_count,
182 key::Event::Input(input::Event::Release {
183 keymap_index: ev_kmi,
184 }),
185 ) if Some(ev_kmi) == self.pressed_keymap_index && active_modifier_count > 0 => {
186 let mut pke = key::KeyEvents::no_events();
188
189 self.active_modifiers[..active_modifier_count as usize]
190 .iter()
191 .for_each(|&m| {
192 let sticky_key_output = key::KeyOutput::from_key_modifiers(m);
193 let vk_ev = key::Event::Input(input::Event::VirtualKeyRelease {
194 key_output: sticky_key_output,
195 });
196 pke.add_event(key::ScheduledEvent::immediate(vk_ev));
197 });
198
199 self.active_modifier_count = 0;
200 self.pressed_keymap_index = None;
201
202 pke
203 }
204 (active_modifier_count, key::Event::Input(input::Event::Press { .. }))
209 if self.pressed_keymap_index.is_some()
210 && self.config.release == StickyKeyRelease::OnNextKeyPress =>
211 {
212 let mut pke = key::KeyEvents::no_events();
215
216 self.active_modifiers[..active_modifier_count as usize]
217 .iter()
218 .for_each(|&m| {
219 let sticky_key_output = key::KeyOutput::from_key_modifiers(m);
220 let vk_ev = key::Event::Input(input::Event::VirtualKeyRelease {
221 key_output: sticky_key_output,
222 });
223 pke.add_event(key::ScheduledEvent::immediate(vk_ev));
224 });
225
226 self.active_modifier_count = 0;
227 self.pressed_keymap_index = None;
228
229 pke
230 }
231 _ => key::KeyEvents::no_events(),
232 }
233 }
234}
235
236#[derive(Debug, Clone, Copy, PartialEq)]
238pub enum Event {
239 ActivateModifiers(key::KeyboardModifiers),
241}
242
243#[derive(Deserialize, Debug, Clone, Copy, PartialEq)]
245pub struct Key {
246 pub sticky_modifiers: key::KeyboardModifiers,
248}
249
250impl Key {
251 pub const fn new(sticky_modifiers: key::KeyboardModifiers) -> Self {
253 Key { sticky_modifiers }
254 }
255
256 pub fn new_pressed_key(&self) -> KeyState {
258 KeyState::new()
259 }
260}
261
262#[derive(Debug, Clone, Copy, PartialEq)]
264pub struct PendingKeyState;
265
266#[derive(Debug, Clone, Copy, Eq, PartialEq)]
268pub enum Behavior {
269 Sticky,
271 Regular,
273}
274
275#[derive(Debug, Clone, Copy, PartialEq)]
277pub struct KeyState {
278 behavior: Behavior,
279}
280
281impl KeyState {
282 pub fn new() -> Self {
284 KeyState {
285 behavior: Behavior::Sticky,
286 }
287 }
288}
289
290impl Default for KeyState {
291 fn default() -> Self {
293 Self::new()
294 }
295}
296
297impl KeyState {
298 pub fn update_state(
300 &mut self,
301 key: &Key,
302 context: &Context,
303 keymap_index: u16,
304 event: key::Event<Event>,
305 ) -> key::KeyEvents<Event> {
306 match self.behavior {
311 Behavior::Sticky => match event {
312 key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput { .. }) => {
313 self.behavior = Behavior::Regular;
316
317 key::KeyEvents::no_events()
318 }
319 key::Event::Input(input::Event::Release {
320 keymap_index: released_index,
321 }) if released_index == keymap_index => {
322 match context.config.activation {
324 StickyKeyActivation::OnStickyKeyRelease => {
325 let sticky_ev = Event::ActivateModifiers(key.sticky_modifiers);
326 let k_ev = key::Event::key_event(keymap_index, sticky_ev);
327
328 let sticky_key_output =
329 key::KeyOutput::from_key_modifiers(key.sticky_modifiers);
330 let vk_ev = key::Event::Input(input::Event::VirtualKeyPress {
331 key_output: sticky_key_output,
332 });
333
334 let mut pke = key::KeyEvents::event(k_ev);
335 pke.add_event(key::ScheduledEvent::immediate(vk_ev));
336 pke
337 }
338 }
339 }
340 _ => key::KeyEvents::no_events(),
341 },
342 Behavior::Regular => key::KeyEvents::no_events(),
343 }
344 }
345
346 pub fn key_output(&self, key: &Key) -> Option<key::KeyOutput> {
348 match self.behavior {
349 Behavior::Sticky => None,
350 Behavior::Regular => Some(key::KeyOutput::from_key_modifiers(key.sticky_modifiers)),
351 }
352 }
353}
354
355#[derive(Debug, Clone, Copy, PartialEq)]
357pub struct System<Keys: Index<usize, Output = Key>> {
358 keys: Keys,
359}
360
361impl<Keys: Index<usize, Output = Key>> System<Keys> {
362 pub const fn new(key_data: Keys) -> Self {
364 Self { keys: key_data }
365 }
366}
367
368impl<R, Keys: Debug + Index<usize, Output = Key>> key::System<R> for System<Keys> {
369 type Ref = Ref;
370 type Context = Context;
371 type Event = Event;
372 type PendingKeyState = PendingKeyState;
373 type KeyState = KeyState;
374
375 fn new_pressed_key(
376 &self,
377 _keymap_index: u16,
378 _context: &Self::Context,
379 Ref(key_index): Ref,
380 ) -> (
381 key::PressedKeyResult<R, Self::PendingKeyState, Self::KeyState>,
382 key::KeyEvents<Self::Event>,
383 ) {
384 let key = &self.keys[key_index as usize];
385 let ks = key.new_pressed_key();
386 let pks = key::PressedKeyResult::Resolved(ks);
387 let pke = key::KeyEvents::no_events();
388 (pks, pke)
389 }
390
391 fn update_pending_state(
392 &self,
393 _pending_state: &mut Self::PendingKeyState,
394 _keymap_index: u16,
395 _context: &Self::Context,
396 _key_ref: Ref,
397 _event: key::Event<Self::Event>,
398 ) -> (Option<key::NewPressedKey<R>>, key::KeyEvents<Self::Event>) {
399 panic!()
400 }
401
402 fn update_state(
403 &self,
404 key_state: &mut Self::KeyState,
405 Ref(key_index): &Self::Ref,
406 context: &Self::Context,
407 keymap_index: u16,
408 event: key::Event<Self::Event>,
409 ) -> key::KeyEvents<Self::Event> {
410 let key = &self.keys[*key_index as usize];
411 key_state.update_state(key, context, keymap_index, event)
412 }
413
414 fn key_output(
415 &self,
416 Ref(key_index): &Self::Ref,
417 key_state: &Self::KeyState,
418 ) -> Option<key::KeyOutput> {
419 let key = &self.keys[*key_index as usize];
420 key_state.key_output(key)
421 }
422}