diff --git a/firmware2/src/ui/backend.rs b/firmware2/src/ui/backend.rs index d618a9a..3f76e89 100644 --- a/firmware2/src/ui/backend.rs +++ b/firmware2/src/ui/backend.rs @@ -1,16 +1,16 @@ use core::{cell::RefCell, time::Duration}; -use alloc::rc::Rc; +use alloc::{rc::Rc, string::ToString}; use esp_hal::time::Instant; -use log::{debug, info}; +use log::{debug, info, warn}; use slint::{ - PhysicalSize, SharedString, WindowSize, + PhysicalSize, SharedString, ToSharedString, WindowSize, platform::{ Key, WindowEvent, software_renderer::{RenderingRotation, RepaintBufferType, Rgb565Pixel, SoftwareRenderer}, }, }; -use xkbcommon::xkb; +use xkbcommon::xkb::{self, Keysym}; use crate::keymap::{KEY_MESSAGE_CHANNEL, TryFromKeysym}; @@ -59,12 +59,42 @@ impl slint::platform::Platform for SlintBackend { { if let Some(window) = self.window.borrow().clone() { // Handle key presses - while let Ok(key_message) = KEY_MESSAGE_CHANNEL.try_receive() { + while let Ok(mut key_message) = KEY_MESSAGE_CHANNEL.try_receive() { debug!("key_message = {key_message:?}"); - let text = key_message.string.map(SharedString::from).or_else(|| { - Key::try_from_keysym(key_message.keysym).map(SharedString::from) - }); + if let Some(string) = key_message.string.as_ref() + && (Keysym::a..=Keysym::z).contains(&key_message.keysym) + { + if let &[code] = string.as_bytes() { + const UNICODE_CTRL_A: char = '\u{1}'; + + let letter_index_from_keysym = + key_message.keysym.raw().wrapping_sub(Keysym::a.raw()); + let letter_index_from_string = + (code as u32).wrapping_sub(UNICODE_CTRL_A as u32); + + if letter_index_from_keysym == letter_index_from_string { + key_message.keysym = + Keysym::new(Keysym::a.raw() + letter_index_from_keysym); + // TODO: Avoid allocation + key_message.string = Some( + ((b'a' + letter_index_from_keysym as u8) as char).to_string(), + ); + + info!( + "Translating CTRL-{letter} to {letter}", + letter = (b'A' + letter_index_from_keysym as u8) as char + ); + } + } + } + + // let text = key_message.string.map(SharedString::from).or_else(|| { + // Key::try_from_keysym(key_message.keysym).map(SharedString::from) + // }); + let text = Key::try_from_keysym(key_message.keysym) + .map(SharedString::from) + .or_else(|| key_message.string.map(SharedString::from)); debug!("text = {text:?}");