pub struct KeymapPolicy {
base_text: String,
base_map: HashMap<u32, (u32, u32)>,
slots: Vec<Option<u32>>,
by_sym: HashMap<u32, usize>,
lru: VecDeque<usize>,
overlay_codes: Vec<u32>,
preferred: usize,
base_bound: HashSet<u32>,
manual_overlay: BTreeMap<u32, u32>,
}Expand description
Seat keymap state: the base text, its reverse keysym map, and the overlay slots.
Fields§
§base_text: String§base_map: HashMap<u32, (u32, u32)>keysym -> (xkb keycode, level) in the base keymap; lowest level wins.
slots: Vec<Option<u32>>slot index -> bound keysym.
by_sym: HashMap<u32, usize>keysym -> slot index.
lru: VecDeque<usize>Slot recycle order, oldest bind first.
overlay_codes: Vec<u32>Overlay keycodes (xkb numbering) in the order free slots take them; slot i lives
at overlay_codes[i].
preferred: usizeHow many of the leading overlay codes a bind prefers, recycling the oldest of them before taking a free code past them: the seat’s text spares, which Chromium types on.
base_bound: HashSet<u32>The text spares the base binds to a keysym other than a vendor one, which an overlay
slot must not shadow. (The virtual-keyboard client’s own codes are base character
keys it shadows on purpose, unshadow taking them back.)
manual_overlay: BTreeMap<u32, u32>Externally-owned overlay binds (keycode -> keysym): selkies resolves its own keysyms and hands the compositor explicit assignments. Held here so every keymap the policy emits carries them, and a policy rebuild (computer-use bind, base-layout swap) keeps them live instead of dropping them until selkies re-sends.
Implementations§
Source§impl KeymapPolicy
impl KeymapPolicy
Sourcepub fn empty() -> Self
pub fn empty() -> Self
Placeholder policy before the seat keymap is known; rebuild_base fills it in.
Sourcepub fn seat() -> Self
pub fn seat() -> Self
The compositor seat’s policy: the text spares (TEXT_SPARE_KEYCODES) first, then the
above-255 range.
Sourcepub fn with_overlay_codes(overlay_codes: Vec<u32>) -> Self
pub fn with_overlay_codes(overlay_codes: Vec<u32>) -> Self
Policy with its own overlay keycodes (xkb numbering), taken in order. The seat
uses empty()’s above-255 range; the virtual-keyboard client typing into a
nested compositor uses the main block’s character keys, which a base character
the batch types takes back (unshadow).
Sourcepub fn rebuild_base(&mut self, base_text: String) -> bool
pub fn rebuild_base(&mut self, base_text: String) -> bool
Replace the base keymap text and rebuild the reverse map. Overlay assignments are
retained (same keycodes), so keycodes already handed out stay valid across the swap.
Returns whether base_text compiled. A string that does not is rejected without
touching any state, so the caller needs no separate validation pass — compiling a
keymap is the expensive part of installing one and doing it twice is pure cost.
Sourcepub fn resolve(&self, keysym: u32) -> Option<(u32, u32)>
pub fn resolve(&self, keysym: u32) -> Option<(u32, u32)>
Resolve keysym without binding: base first, then an existing overlay slot.
Sourcefn slot_at(&self, keycode: u32) -> Option<usize>
fn slot_at(&self, keycode: u32) -> Option<usize>
The occupied overlay slot on keycode, whose keysym shadows the base’s there.
Sourcefn unshadow(
&mut self,
keysyms: &[u32],
pressed: &HashSet<u32>,
plain_only: bool,
changed: &mut bool,
) -> HashSet<u32>
fn unshadow( &mut self, keysyms: &[u32], pressed: &HashSet<u32>, plain_only: bool, changed: &mut bool, ) -> HashSet<u32>
Unbind every overlay slot shadowing a base keycode the batch presses, unless it is held, and return those keycodes so the batch’s own binds skip them.
Sourcepub fn resolves_plain(&self, keysym: u32) -> bool
pub fn resolves_plain(&self, keysym: u32) -> bool
True when keysym resolves at level 0 (base or overlay) — i.e. typable without
synthetic modifiers.
Sourcepub fn bind_many(
&mut self,
keysyms: &[u32],
pressed: &HashSet<u32>,
) -> (Vec<(u32, u32)>, bool)
pub fn bind_many( &mut self, keysyms: &[u32], pressed: &HashSet<u32>, ) -> (Vec<(u32, u32)>, bool)
Resolve every keysym, overlay-binding the unresolvable ones. Returns one
(keycode, level) per input keysym ((0, 0) when it cannot be bound) plus whether the
keymap changed and must be re-applied — at most ONE swap per call, however many new
keysyms were bound. Slots whose keycode is in pressed are never recycled.
Sourcepub fn bind_many_plain(
&mut self,
keysyms: &[u32],
pressed: &HashSet<u32>,
) -> (Vec<u32>, bool)
pub fn bind_many_plain( &mut self, keysyms: &[u32], pressed: &HashSet<u32>, ) -> (Vec<u32>, bool)
Like bind_many but only accepts level-0 resolutions: a keysym reachable in the
base solely behind a modifier (e.g. A behind Shift) is overlay-bound instead, so the
caller can inject it without synthesizing modifiers. Returns keycodes (0 = unbindable).
fn bind_one( &mut self, sym: u32, pressed: &HashSet<u32>, reserved: &HashSet<u32>, plain_only: bool, changed: &mut bool, ) -> (u32, u32)
Sourcefn recycle_slot(
&mut self,
pressed: &HashSet<u32>,
reserved: &HashSet<u32>,
below: usize,
) -> Option<usize>
fn recycle_slot( &mut self, pressed: &HashSet<u32>, reserved: &HashSet<u32>, below: usize, ) -> Option<usize>
Oldest slot below below whose keycode is neither held down nor pressed for its base
keysym by this batch; a held keycode must keep its meaning until its release has been
delivered.
Sourcefn takes(&self, keycode: u32, reserved: &HashSet<u32>) -> bool
fn takes(&self, keycode: u32, reserved: &HashSet<u32>) -> bool
Whether a slot may hold keycode: not one this batch presses for its base keysym,
not a text spare the base binds to a real keysym, and not one selkies’ overlay holds.
Sourcepub fn set_manual_overlay(&mut self, binds: &[(u32, u32)])
pub fn set_manual_overlay(&mut self, binds: &[(u32, u32)])
Replace the externally-owned overlay binds (keycode -> keysym). selkies resolves its
own keysyms and re-sends the whole set on every change, so a full replace is the
contract. They then ride along in every keymap_text, so a base-layout swap or a
computer-use policy bind re-applies them instead of dropping them.
A slot on a keycode selkies now binds gives it up, so its keysym is bound afresh
elsewhere when next typed.
Sourcepub fn keymap_text(&self) -> String
pub fn keymap_text(&self) -> String
The full seat keymap: the base text with every occupied policy overlay slot and every
externally-owned bind spliced into the xkb_keycodes and xkb_symbols sections (and
maximum raised to cover them). With neither, the base text verbatim. A manual bind
sharing a keycode with a policy slot is emitted last, so its symbol wins.
Auto Trait Implementations§
impl Freeze for KeymapPolicy
impl RefUnwindSafe for KeymapPolicy
impl Send for KeymapPolicy
impl Sync for KeymapPolicy
impl Unpin for KeymapPolicy
impl UnsafeUnpin for KeymapPolicy
impl UnwindSafe for KeymapPolicy
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more