pub struct LookupTable { /* private fields */ }
Expand description
A keysym lookup table.
This type allows looking up keysyms and characters generated by key-press events. It
is created by calling Builder::build_lookup_table
.
§Example
fn get_string(
table: &LookupTable,
group: GroupIndex,
modifiers: ModifierMask,
keycode: Keycode,
) -> String {
table
.lookup(group, modifiers, keycode)
.into_iter()
.flat_map(|p| p.char())
.collect()
}
§Key Repeat
A key can be configured to repeat. In this case, the client should periodically emulate key-press events until the next repeating key is pressed or this key is released.
This property can be accessed with the Lookup::repeats
function.
fn need_key_repeat_events(
table: &LookupTable,
group: GroupIndex,
modifiers: ModifierMask,
keycode: Keycode,
) -> bool {
table
.lookup(group, modifiers, keycode)
.repeats()
}
§Consumed Modifiers
The lookup process might consume some of the input modifiers. These modifiers should be ignored when the produced keysyms are used in keyboard shortcuts.
This remaining modifiers can be accessed with the Lookup::remaining_mods
function.
fn get_keysyms_for_shortcuts(
table: &LookupTable,
group: GroupIndex,
modifiers: ModifierMask,
keycode: Keycode,
) -> impl Iterator<Item = (ModifierMask, Keysym)> + use<'_> {
let lookup = table.lookup(group, modifiers, keycode);
lookup.into_iter().map(move |p| (lookup.remaining_mods(), p.keysym()))
}
§Caps Transformation
If the remaining modifiers contain the caps modifier, the keysym iterator will automatically perform caps transformation. That is, all keysyms will be replaced by their uppercase version.
This behavior can be disabled by using Lookup::with_caps_transform
and
Lookup::set_caps_transform
.
fn disable_caps_transform(
table: &LookupTable,
group: GroupIndex,
modifiers: ModifierMask,
keycode: Keycode,
) -> impl Iterator<Item = KeysymProps> + use<'_> {
table
.lookup(group, modifiers, keycode)
.with_caps_transform(false)
.into_iter()
}
§Ctrl Transformation
If the remaining modifiers contain the ctrl modifier, the keysym iterator will automatically perform ctrl transformation. This transform only affects the produced characters but not the produced keysyms.
This behavior can be disabled by using Lookup::with_ctrl_transform
and
Lookup::set_ctrl_transform
.
fn disable_ctrl_transform(
table: &LookupTable,
group: GroupIndex,
modifiers: ModifierMask,
keycode: Keycode,
) -> impl Iterator<Item = char> + use<'_> {
table
.lookup(group, modifiers, keycode)
.with_ctrl_transform(false)
.into_iter()
.flat_map(|p| p.char())
}
Ctrl transformation applies the following modification:
let output = match input {
b'@'..=b'~' => input & 0x1f,
b' ' | b'2' => 0,
b'3'..=b'7' => input - 0x1b,
b'8' => 0x7f,
b'/' => 0x1f,
_ => input,
};
§Ctrl Transformation Fallback
If
- the preconditions for ctrl transformation are met, and
- the key press would otherwise produce a single keysym, and
- that keysym has a value greater than 127, and
- the key has another group that, when used with the same modifiers, would produce a single keysym less than or equal to 127,
then, instead of using the original keysym, the keysym form the first such group is used.
Caps and ctrl transformations are then applied to that keysym.
This is sometimes used to allow users of non-latin keyboard layouts to use latin keysyms in keyboard shortcuts.
This behavior can be disabled by using Lookup::with_ctrl_fallback
and
Lookup::set_ctrl_fallback
.
fn disable_ctrl_fallback(
table: &LookupTable,
group: GroupIndex,
modifiers: ModifierMask,
keycode: Keycode,
) -> impl Iterator<Item = char> + use<'_> {
table
.lookup(group, modifiers, keycode)
.with_ctrl_fallback(false)
.into_iter()
.flat_map(|p| p.char())
}
Implementations§
Source§impl LookupTable
impl LookupTable
Sourcepub fn lookup(
&self,
group: GroupIndex,
mods: ModifierMask,
keycode: Keycode,
) -> Lookup<'_>
pub fn lookup( &self, group: GroupIndex, mods: ModifierMask, keycode: Keycode, ) -> Lookup<'_>
Looks up the keysyms associated with a key press.
The group
and mods
should be the effective group and effective modifiers
computed by the compositor.
In wayland, the effective modifiers are the bitwise OR of the pressed, latched,
and locked modifiers. This can be managed with the Components
type.
§Example
An application using the wayland-client crate might use this function as follows:
struct State {
lookup_table: LookupTable,
group: GroupIndex,
mods: ModifierMask,
}
impl Dispatch<WlKeyboard, ()> for State {
fn event(
state: &mut State,
_: &WlKeyboard,
event: wl_keyboard::Event,
_: &(),
_: &Connection,
_: &QueueHandle<State>,
) {
use wl_keyboard::Event;
match event {
Event::Modifiers {
mods_depressed, mods_latched, mods_locked, group, ..
} => {
state.group = GroupIndex(group);
state.mods = ModifierMask(mods_depressed | mods_latched | mods_locked);
}
Event::Key { key, state: WEnum::Value(WlKeyState::Pressed), .. } => {
let key = Keycode::from_evdev(key);
for keysym in state.lookup_table.lookup(state.group, state.mods, key) {
println!("{keysym:?}");
}
}
_ => { },
}
}
}
Sourcepub fn effective_group(
&self,
group: GroupIndex,
keycode: Keycode,
) -> Option<GroupIndex>
pub fn effective_group( &self, group: GroupIndex, keycode: Keycode, ) -> Option<GroupIndex>
Returns the effective group that will be used for the keycode.
The group
parameter should be the effective group computed by the compositor.
This function will then return the effective group for the specific key.
These values can differ when the key has fewer groups than the maximum number of
groups in the keymap. In this case, the effective group is calculated using
the Redirect
setting of the key.
Source§impl LookupTable
impl LookupTable
Sourcepub fn to_xkb_keymap(&self) -> Keymap
pub fn to_xkb_keymap(&self) -> Keymap
Creates a client-side XKB keymap from a lookup table.
The created keymap does not contain any actions. Clients trying to implement how-to-type logic will not be able to determine which key presses trigger which modifiers or groups.
The keymap will contain modmap entries mapping all keys producing Alt_L
or
Alt_R
to Mod1
.
§Example
let mut builder = Builder::default();
{
let gt = GroupType::builder(ModifierMask::SHIFT)
.map(ModifierMask::SHIFT, 1)
.build();
let mut gb = GroupBuilder::new(0, >);
let mut level = LevelBuilder::new(0);
level.keysyms(&[syms::a]);
gb.add_level(level);
let mut level = LevelBuilder::new(1);
level.keysyms(&[syms::A]);
gb.add_level(level);
let mut key = KeyBuilder::new(Keycode::from_x11(9));
key.repeats(true);
key.add_group(gb);
builder.add_key(key)
}
{
let gt = GroupType::builder(ModifierMask::NONE).build();
let mut level = LevelBuilder::new(0);
level.keysyms(&[syms::Alt_L]);
let mut gb = GroupBuilder::new(0, >);
gb.add_level(level);
let mut key = KeyBuilder::new(Keycode::from_x11(10));
key.add_group(gb);
builder.add_key(key)
}
let map = builder.build_lookup_table().to_xkb_keymap();
println!("{:#}", map.format());
Outputs
xkb_keymap {
xkb_keycodes {
minimum = 8;
maximum = 255;
indicator 1 = "DUMMY";
<9> = 9;
<10> = 10;
};
xkb_types {
virtual_modifiers Dummy;
type "type0" {
modifiers = Shift;
map[Shift] = Level2;
};
type "type1" {
modifiers = None;
};
};
xkb_compat {
interpret VoidSymbol {
repeat = false;
};
};
xkb_symbols {
modmap Mod1 { <10> };
key.repeat = true;
key <9> {
type[Group1] = "type0",
symbols[Group1] = [ a, A ]
};
key <10> {
repeat = false,
type[Group1] = "type1",
symbols[Group1] = [ Alt_L ]
};
};
};
Trait Implementations§
Source§impl Clone for LookupTable
impl Clone for LookupTable
Source§fn clone(&self) -> LookupTable
fn clone(&self) -> LookupTable
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more