diff --git a/src/core/button.rs b/src/core/button.rs index f0f156a..7343c75 100644 --- a/src/core/button.rs +++ b/src/core/button.rs @@ -488,6 +488,11 @@ impl Button { let meta_pressed = modifiers[MOD_META - 1] != ModState::Released; let mods_pressed = ctrl_pressed || alt_pressed || meta_pressed; + if part.sym() == Keysym::Num_Lock + || part.sym() == Keysym::Caps_Lock { + return; + } + if part.key_available() && mods_pressed { kbd.press(part.sym()); kbd.release(part.sym()); @@ -499,6 +504,30 @@ impl Button { } } + fn release_layout_switcher(&mut self, sym: Keysym) -> DrawOperation + { + let old_width = self.layout.width(); + let old_height = self.layout.height(); + + match sym { + Keysym::Num_Lock => { + self.layout.switch_numeric(); + }, + Keysym::Caps_Lock => { + self.layout.switch_text(); + }, + _ => return DrawOperation::Key, + } + + self.layout.update_keys_supported(&self.kbd); + self.kbd.change_layout(&self.layout); + + self.x_scale *= self.layout.width() / old_width; + self.y_scale *= self.layout.height() / old_height; + + DrawOperation::Labels + } + fn is_normal_key_pressed(&self) -> bool { for id in &self.timers { @@ -586,12 +615,14 @@ impl Button { key.parts[press.part].release(); + let keysym = key.parts[press.part].sym(); let modifier = key.parts[press.part].modifier_id(); if modifier == 0 { Self::emit(&mut self.kbd, &key.parts[press.part], &self.modifiers); } let draw = self.release_mod(modifier); + let draw = draw + self.release_layout_switcher(keysym); let press = self.presses[id].as_ref().unwrap(); let key = self.layout.locate_key(press.x1, press.y1).unwrap(); diff --git a/src/core/layout.rs b/src/core/layout.rs index 8691970..9e0cf1b 100644 --- a/src/core/layout.rs +++ b/src/core/layout.rs @@ -69,6 +69,7 @@ impl KeyValue { } } +#[derive(Clone)] pub struct Part { orig: KeyValue, val: KeyValue, @@ -404,6 +405,7 @@ impl Part { } } +#[derive(Clone)] pub struct Key { pub parts: [Part; 9], pub x1: f64, @@ -441,7 +443,7 @@ impl Key { } } -const KEYSYMS: [(&str, Keysym, &str); 21] = [ +const KEYSYMS: [(&str, Keysym, &str); 23] = [ ("\\#", Keysym::numbersign, "#"), ("\\?", Keysym::question, "?"), ("\\@", Keysym::at, "@"), @@ -461,10 +463,13 @@ const KEYSYMS: [(&str, Keysym, &str); 21] = [ ("right", Keysym::Right, "→"), ("shift", Keysym::Shift_L, "⇧"), ("space", Keysym::space, " "), + ("switch_numeric", Keysym::Num_Lock, "123+"), + ("switch_text", Keysym::Caps_Lock, "ABC"), ("tab", Keysym::Tab, "⭾"), ("up", Keysym::Up, "↑"), ]; +#[derive(Clone)] struct LayoutFile { rows: Vec>, has_bottom_row: bool, @@ -604,6 +609,10 @@ impl LayoutFile { } pub struct Layout { + main_layout: LayoutFile, + numeric: LayoutFile, + bottom_row: LayoutFile, + rows: Vec>, width: f64, height: f64, @@ -652,6 +661,35 @@ impl Layout { } } + fn open_layout(&mut self, data: LayoutFile) + { + self.rows = data.rows; + self.width = data.width; + self.height = data.height; + + if data.has_bottom_row { + let old_height = self.height; + self.height += self.bottom_row.height; + + self.rows.reserve(self.bottom_row.rows.len()); + for row in &self.bottom_row.rows { + let mut new_row = Vec::with_capacity(row.len()); + + for key in row { + new_row.push(Key { + parts: key.parts.clone(), + x1: key.x1 * self.width / self.bottom_row.width, + y1: old_height + key.y1, + x2: key.x2 * self.width / self.bottom_row.width, + y2: old_height + key.y2, + }); + } + + self.rows.push(new_row); + } + } + } + pub fn load(cfg: &Configuration) -> Result { let dir = Path::new("/usr/share/unfettered-keyboard/layouts"); @@ -659,37 +697,25 @@ impl Layout { let path = dir.join(cfg.layout()); let main_layout = LayoutFile::load(path)?; + let path = dir.join("numeric.xml"); + let numeric = LayoutFile::load(path)?; + + let path = dir.join("bottom_row.xml"); + let bottom_row = LayoutFile::load(path)?; + let mut layout = Layout { - rows: main_layout.rows, - width: main_layout.width, - height: main_layout.height, + main_layout, + numeric, + bottom_row, + + rows: Vec::new(), + width: 0.0, + height: 0.0, text_supp: false, }; - if main_layout.has_bottom_row { - let path = dir.join("bottom_row.xml"); - let bottom_row = LayoutFile::load(path)?; - - let old_height = layout.height; - layout.height += bottom_row.height; - - layout.rows.reserve(bottom_row.rows.len()); - for row in bottom_row.rows { - let mut new_row = Vec::with_capacity(row.len()); - - for key in row { - new_row.push(Key { - parts: key.parts, - x1: key.x1 * layout.width / bottom_row.width, - y1: old_height + key.y1, - x2: key.x2 * layout.width / bottom_row.width, - y2: old_height + key.y2, - }); - } - - layout.rows.push(new_row); - } - } + let data = layout.main_layout.clone(); + layout.open_layout(data); Ok(layout) } @@ -784,4 +810,18 @@ impl Layout { } } } + + pub fn switch_numeric(&mut self) + { + let data = self.numeric.clone(); + self.open_layout(data); + self.set_text_supported(self.text_supp); + } + + pub fn switch_text(&mut self) + { + let data = self.main_layout.clone(); + self.open_layout(data); + self.set_text_supported(self.text_supp); + } }