core: add meta key

Some applications have features (like typing Unicode codepoints in foot)
that can only be used with key presses. Add a Meta key to allow the user
to always send a keypress.
This commit is contained in:
Richard Acayan 2024-09-04 21:31:04 -04:00
parent 0ebf6a8d5b
commit f3ba955ae4
3 changed files with 28 additions and 6 deletions

View file

@ -11,6 +11,7 @@ use crate::core::Part;
use crate::core::layout::Key;
use crate::core::layout::MOD_ALT;
use crate::core::layout::MOD_CTRL;
use crate::core::layout::MOD_META;
use crate::core::layout::MODIFIERS_MAX;
use std::collections::VecDeque;
use std::convert::TryInto;
@ -239,11 +240,11 @@ impl<D: Display, K: Keyboard> Button<D, K> {
if self.modifiers[modifier - 1] == old {
self.modifiers[modifier - 1] = new;
if new == ModState::Released && !Layout::is_keysym_modifier(modifier) {
if new == ModState::Released && Layout::is_pressable_modifier(modifier) {
self.kbd.release(Layout::modifier_keysym(modifier));
}
if old == ModState::Released && !Layout::is_keysym_modifier(modifier) {
if old == ModState::Released && Layout::is_pressable_modifier(modifier) {
self.kbd.press(Layout::modifier_keysym(modifier));
}
@ -468,7 +469,8 @@ impl<D: Display, K: Keyboard> Button<D, K> {
{
let ctrl_pressed = modifiers[MOD_CTRL - 1] != ModState::Released;
let alt_pressed = modifiers[MOD_ALT - 1] != ModState::Released;
let mods_pressed = ctrl_pressed || alt_pressed;
let meta_pressed = modifiers[MOD_META - 1] != ModState::Released;
let mods_pressed = ctrl_pressed || alt_pressed || meta_pressed;
if part.key_available() && mods_pressed {
kbd.press(part.sym());

View file

@ -97,7 +97,7 @@ struct Label<'a> {
small: bool,
}
const LABELS: [Label; 21] = [
const LABELS: [Label; 22] = [
Label { label: "Alt",
secondary: true, small: true, },
Label { label: "Ctrl",
@ -112,6 +112,8 @@ const LABELS: [Label; 21] = [
secondary: true, small: true, },
Label { label: "Ins",
secondary: true, small: true, },
Label { label: "Meta",
secondary: true, small: true, },
Label { label: "\u{2190}", // LEFTWARDS ARROW
secondary: true, small: false, },
Label { label: "\u{2191}", // UPWARDS ARROW

View file

@ -56,7 +56,8 @@ pub const MOD_SHIFT: usize = 1;
pub const MOD_CTRL: usize = 2;
pub const MOD_ALT: usize = 3;
pub const MOD_FN: usize = 4;
pub const MODIFIERS_MAX: usize = 4;
pub const MOD_META: usize = 5;
pub const MODIFIERS_MAX: usize = 5;
#[derive(Clone)]
struct KeyValue(Keysym, String);
@ -417,6 +418,7 @@ impl Part {
Keysym::Control_L => MOD_CTRL,
Keysym::Alt_L => MOD_ALT,
Keysym::XF86_Fn => MOD_FN,
Keysym::Meta_L => MOD_META,
_ => 0,
}
}
@ -501,7 +503,7 @@ pub struct Layout {
text_supp: bool,
}
const KEYSYMS: [(&str, Keysym, &str); 20] = [
const KEYSYMS: [(&str, Keysym, &str); 21] = [
("\\#", Keysym::numbersign, "#"),
("\\?", Keysym::question, "?"),
("\\@", Keysym::at, "@"),
@ -517,6 +519,7 @@ const KEYSYMS: [(&str, Keysym, &str); 20] = [
("fn", Keysym::XF86_Fn, "Fn"),
("left", Keysym::Left, ""),
("loc alt", Keysym::Alt_L, "Alt"),
("loc meta", Keysym::Meta_L, "Meta"),
("right", Keysym::Right, ""),
("shift", Keysym::Shift_L, ""),
("space", Keysym::space, " "),
@ -533,6 +536,20 @@ impl Layout {
}
}
/*
* Check if the modifier can be emitted as a key event.
*
* Modifiers that modify the key values (e.g. the Fn key and any accents)
* should usually not be emitted as key events to applications, and their
* only purpose is to modify the key values. The Meta modifier should also
* be inhibited from emitting a key event, because its purpose is to make
* every key value emit a key press.
*/
pub fn is_pressable_modifier(modifier: usize) -> bool
{
!Self::is_keysym_modifier(modifier) && modifier != MOD_META
}
pub fn is_label_modifier(modifier: usize) -> bool
{
// Shift does not change the keysym used for input, but changes the
@ -547,6 +564,7 @@ impl Layout {
MOD_CTRL => Keysym::Control_L,
MOD_ALT => Keysym::Alt_L,
MOD_FN => Keysym::XF86_Fn,
MOD_META => Keysym::Meta_L,
_ => Keysym::NoSymbol,
}
}