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(Debug, Clone, Copy, PartialEq)]
12#[cfg_attr(feature = "std", derive(Deserialize))]
13pub enum StickyKeyActivation {
14 OnStickyKeyRelease,
16 }
20
21#[derive(Debug, Clone, Copy, PartialEq)]
23#[cfg_attr(feature = "std", derive(Deserialize))]
24pub enum StickyKeyRelease {
25 OnModifiedKeyRelease,
27 OnNextKeyPress,
29}
30
31#[derive(Debug, Clone, Copy, PartialEq)]
33#[cfg_attr(feature = "std", derive(Deserialize))]
34pub struct Config {
35 #[cfg_attr(feature = "std", serde(default = "default_activation"))]
37 pub activation: StickyKeyActivation,
38 #[cfg_attr(feature = "std", serde(default = "default_release"))]
40 pub release: StickyKeyRelease,
41}
42
43#[cfg(feature = "std")]
44fn default_activation() -> StickyKeyActivation {
45 DEFAULT_CONFIG.activation
46}
47
48#[cfg(feature = "std")]
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(self.sticky_modifiers)
259 }
260}
261
262impl key::Key for Key {
263 type Context = crate::init::Context;
264 type Event = crate::init::Event;
265 type PendingKeyState = crate::init::PendingKeyState;
266 type KeyState = crate::init::KeyState;
267
268 fn new_pressed_key(
269 &self,
270 _context: &Self::Context,
271 _key_path: key::KeyPath,
272 ) -> (
273 key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>,
274 key::KeyEvents<Self::Event>,
275 ) {
276 let ks = self.new_pressed_key();
277 let pks = key::PressedKeyResult::Resolved(ks.into());
278 let pke = key::KeyEvents::no_events();
279 (pks, pke)
280 }
281
282 fn handle_event(
283 &self,
284 _pending_state: &mut Self::PendingKeyState,
285 _context: &Self::Context,
286 _key_path: key::KeyPath,
287 _event: key::Event<Self::Event>,
288 ) -> (
289 Option<key::PressedKeyResult<Self::PendingKeyState, Self::KeyState>>,
290 key::KeyEvents<Self::Event>,
291 ) {
292 panic!()
293 }
294
295 fn lookup(
296 &self,
297 _path: &[u16],
298 ) -> &dyn key::Key<
299 Context = Self::Context,
300 Event = Self::Event,
301 PendingKeyState = Self::PendingKeyState,
302 KeyState = Self::KeyState,
303 > {
304 self
305 }
306}
307
308#[derive(Debug, Clone, Copy, Eq, PartialEq)]
310pub enum Behavior {
311 Sticky,
313 Regular,
315}
316
317#[derive(Debug, Clone, Copy, PartialEq)]
319pub struct KeyState {
320 sticky_modifiers: key::KeyboardModifiers,
321 behavior: Behavior,
322}
323
324impl KeyState {
325 pub fn new(sticky_modifiers: key::KeyboardModifiers) -> Self {
327 KeyState {
328 sticky_modifiers,
329 behavior: Behavior::Sticky,
330 }
331 }
332}
333
334impl KeyState {
335 pub fn handle_event(
337 &mut self,
338 context: &Context,
339 keymap_index: u16,
340 event: key::Event<Event>,
341 ) -> key::KeyEvents<Event> {
342 match self.behavior {
347 Behavior::Sticky => match event {
348 key::Event::Keymap(keymap::KeymapEvent::ResolvedKeyOutput { .. }) => {
349 self.behavior = Behavior::Regular;
352
353 key::KeyEvents::no_events()
354 }
355 key::Event::Input(input::Event::Release {
356 keymap_index: released_index,
357 }) if released_index == keymap_index => {
358 match context.config.activation {
360 StickyKeyActivation::OnStickyKeyRelease => {
361 let sticky_ev = Event::ActivateModifiers(self.sticky_modifiers);
362 let k_ev = key::Event::key_event(keymap_index, sticky_ev);
363
364 let sticky_key_output =
365 key::KeyOutput::from_key_modifiers(self.sticky_modifiers);
366 let vk_ev = key::Event::Input(input::Event::VirtualKeyPress {
367 key_output: sticky_key_output,
368 });
369
370 let mut pke = key::KeyEvents::event(k_ev);
371 pke.add_event(key::ScheduledEvent::immediate(vk_ev));
372 pke
373 }
374 }
375 }
376 _ => key::KeyEvents::no_events(),
377 },
378 Behavior::Regular => key::KeyEvents::no_events(),
379 }
380 }
381
382 pub fn key_output(&self) -> Option<key::KeyOutput> {
384 match self.behavior {
385 Behavior::Sticky => None,
386 Behavior::Regular => Some(key::KeyOutput::from_key_modifiers(self.sticky_modifiers)),
387 }
388 }
389}