pub struct KeyPress {
pub code: KeyCode,
pub physical: KeyCode,
pub mods: KeyMods,
pub text: Option<String>,
pub repeat: bool,
pub location: KeyLocation,
pub locks: KeyLocks,
}Expand description
One key press, delivered to whatever holds key focus. Carries both the
binding view (code + mods) and the typing view (text), so an app can
serve a modal keymap and an insert mode from the same event.
Fields§
§code: KeyCode§physical: KeyCodeWhere the key is, independent of the layout: the US-QWERTY key at
that position, in the same vocabulary as code. The key left of B
is Char('v') on every layout on earth, so a chord map written
against this one binds a shape rather than a character — what a
game’s WASD wants, and what a keymap wants when it would rather be
wrong about the label than wrong about the finger.
code is usually the better default; see its note. Unknown when
the platform reports a position this vocabulary cannot name.
mods: KeyMods§text: Option<String>What this press would insert, if anything — already resolved through
the keyboard layout. None for pure navigation and chords.
repeat: boolSet when the press came from OS key repeat.
location: KeyLocationWhich of a key’s twins this is: the left or right modifier, the
keypad’s digit or the main block’s (see KeyLocation).
locks: KeyLocksCaps Lock and Num Lock as the press left them: a lock key’s own press reports the state it turned the lock to, on every platform.
Implementations§
Source§impl KeyPress
impl KeyPress
Sourcepub fn new(code: KeyCode, mods: KeyMods) -> Self
pub fn new(code: KeyCode, mods: KeyMods) -> Self
A press whose position is its own code — what a layout that agrees
with US-QWERTY produces, and the sane reading of an injected press:
naming a key is saying which key was pressed. The one fold: an
ASCII letter’s position is its lower-case letter, since a window
reports physical from a table that never sees Shift (Z beside
code: "Z" for ⇧Z would be a pair no window ever sends). A physical
a caller spells is delivered as spelled — this
is only the default, which was already a guess.
Sourcepub fn with_location(self, location: KeyLocation) -> Self
pub fn with_location(self, location: KeyLocation) -> Self
Says which of a key’s twins this is (Numpad for the keypad’s,
Left / Right for a modifier’s).
Sourcepub fn with_locks(self, locks: KeyLocks) -> Self
pub fn with_locks(self, locks: KeyLocks) -> Self
Says what the lock keys held at the press.
Sourcepub fn with_physical(self, physical: KeyCode) -> Self
pub fn with_physical(self, physical: KeyCode) -> Self
Says which physical key produced this press, when the layout put a
different code on it (⌥v on Dvorak: code v, physical .).
Sourcepub fn from_layout(layout: KeyCode, physical: KeyCode, mods: KeyMods) -> Self
pub fn from_layout(layout: KeyCode, physical: KeyCode, mods: KeyMods) -> Self
The press a driver builds from the two things the OS tells it: what
the active layout put on the key, and which key it was. Every driver
resolves code the same way because they all come through here.
The layout wins while it speaks ASCII, so a chord lands on the key
the user can see — Dvorak’s ⌥v on the key printed V, AZERTY’s
⌘a on the one printed A, QWERTZ’s ⌘z on the one printed Z. A
layout that produces anything else (Cyrillic, Greek, Hebrew, Arabic)
would make every Latin keymap in every app match nothing at all, so
the US-QWERTY letter at that position stands in; this is the rule
browsers use to keep ⌘C copying on a Russian layout. A layout key
this vocabulary cannot name falls back the same way.
The stand-in is what US-QWERTY would have produced for the same
press, Shift included: a window reports physical from a table
that never sees Shift, so ⇧ on the key printed J is
J, not j, and ⇧ on the key printed ; is : — the key a vim
hand on a Russian layout reaches for, and gets ; from otherwise.
Except under Alt, where the stand-in is the unshifted position.
What a layout puts on an ⌥ key is a composed character (macOS US
⌥⇧J is Ô), so a driver resolving a chord reads the key with
every modifier stripped — the winit runner’s j for ⌥⇧J, on a
US layout and a Russian one alike — and a host that passes the
composed character lands here instead. Folding Shift here too is
what makes the two agree; mods still says Shift was held.
Caps Lock is not read here: it is KeyPress::locks, set after,
so the stand-in follows Shift alone and a Caps-Locked non-Latin
key stands in as the lower-case letter, where US-QWERTY would
print the upper-case one.
physical is reported either way, for a keymap that would rather
bind the finger than the label.
This judges each key by itself, which is all a driver that cannot
ask about the layout can do; one that can says so through
KeyPress::from_layout_in.
Sourcepub fn from_layout_in(
layout: KeyCode,
physical: KeyCode,
mods: KeyMods,
script: LayoutScript,
) -> Self
pub fn from_layout_in( layout: KeyCode, physical: KeyCode, mods: KeyMods, script: LayoutScript, ) -> Self
KeyPress::from_layout on a layout whose alphabet the driver
knows. On a LayoutScript::NonLatin one the US-QWERTY key stands
in for every character the layout put where US-QWERTY has another,
ASCII or not, so macOS Russian’s ] on the key printed ` is
`, its " on ⇧2 is @, and Windows Russian’s . on the key
printed / is /. A key that already is its
position’s character — a digit, the keypad’s — keeps it, and a key
at a position this vocabulary cannot name (ISO’s extra key) keeps
the layout’s, there being nothing to stand in.
pub fn with_text(self, text: impl Into<String>) -> Self
Sourcepub fn same_key(&self, other: &KeyPress) -> bool
pub fn same_key(&self, other: &KeyPress) -> bool
Whether other is a press or release of the same key as this one
— how a release is matched to the press it lets go of, and a repeat
to the press it repeats. By position when the platform reported
one, because code moves under a held key: hold w, press Shift,
and the OS repeat arrives as W, which by code would be a second
key held, with the first stuck down until focus moved. A
press whose position the vocabulary could not name is matched on
code, which is all it has. And by KeyPress::location too:
the keypad’s 1 and the main block’s share a position’s name,
as the two Shifts do, and are two keys.
Sourcepub fn edit_event(&self) -> Option<InputEvent>
pub fn edit_event(&self) -> Option<InputEvent>
The second event a real key press produces, after its
InputEvent::KeyDown — the other half of what a window does with
one key going down, and the one table that says which key is which.
A press is two channels, and every driver drives both, in this
order. KeyDown goes to whatever holds key focus, so an app that
owns its keyboard hears the raw key; this is what the core is
asked to do with the same key — Escape dismisses a modal, Tab walks
the focus ring, the arrows nudge a focused slider, Space presses a
focused control, a printable character reaches the focused editor.
A test that sent only KeyDown got the first channel and none of
the second, which is why key_down("escape") left a modal open;
crate::Core::press is the pair.
None for a key this vocabulary does not name — a function key,
Insert — and for every chord, which carries no text because it
inserts nothing. The press still stands on the sink channel.
Trait Implementations§
impl Eq for KeyPress
impl StructuralPartialEq for KeyPress
Auto Trait Implementations§
impl Freeze for KeyPress
impl RefUnwindSafe for KeyPress
impl Send for KeyPress
impl Sync for KeyPress
impl Unpin for KeyPress
impl UnsafeUnpin for KeyPress
impl UnwindSafe for KeyPress
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.