keyseq
Specify key chords using Ctrl-A short-hand, supports bevy and
winit.
Objective
-
Specify key chords in code the same way as they are specified in documentation.
-
For the sake of finding key chords in code, prefer one way of describing the keys, e.g., accept "Ctrl-A"; do not accept "control-A" or "C-A". ("Ctrl+A" can be accepted by using the "permit-plus" feature flag.)
Install
; # OR --features winit
Principal Macros
- The
pkey!macro specifies a physical key chord, e.g.,pkey! { Ctrl-A }. - The
pkeyseq!macro specifies a physical key chord sequence, e.g.,pkeyseq! { Ctrl-A Alt-B C }. - The
lkey!macro specifies a logical key chord, .e.g,lkey! { Ctrl-a }. - The
lkeyseq!macro specifies a logical key chord sequence, e.g.lkeyseq! { Ctrl-a Alt-b c }.
Concepts
- A physical key denotes a particular key on the keyboard. It emits a key code that does not change no matter what modifiers are held down. For instance there is a physical 'Q' key, often to the right of the tab key. There is no physical lower-case 'q' key.
- A logical key is specified by what the key produces. If pressing the key produces a 'q' character, then it is logically a 'q' key.
Usage
Winit
With the "winit" feature the keyseq::winit::pkey! macro returns a
(Modifiers, KeyCode) tuple.
Physical Keys
use ;
use KeyCode;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Physical Key Sequences
# use Modifiers;
# use KeyCode;
use pkeyseq;
assert_eq!;
Logical Keys
With the "winit" feature the keyseq::winit::lkey! macro returns a
(Modifiers, Key) tuple.
use ;
use Key;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Logical Key Sequences
# use Modifiers;
# use Key;
use lkeyseq;
assert_eq!;
No lower case physical keys
The following code will fail to compile. It insists on a capital 'A' for specifying the A key.
# use pkey;
let = pkey! ; // error: Use uppercase key names for physical keys
Strict modifier order
With the "strict-order" feature enabled by default, modifiers out of order will produce compiler errors. Without the feature, it will emit warnings.
# use pkey;
let _ = pkey! ; // error: Modifiers must occur in this order: control, Alt, Shift, Super.
Why not use winit::keyboard::ModifiersState?
Why return keyseq::Modifiers and not winit's own ModifiersState? Both
keyseq::Modifiers and winit::keyboard::ModifiersState are generated using
the bitflags crate. Originally this
crate did return winit's native modifiers struct because it desugared to nearly
the same thing:
// keyseq::winit::pkey! { Ctrl-Alt-A } desugared to
// keyseq::bevy::pkey! { Ctrl-Alt-A } desugars to
However, this these bitflags put together with bit-or pipes had a problem with match expressions.
When desugared the bit-or | is now interpretered as a match-or |, which does
not match Ctrl-Alt; it only matches Ctrl or Alt or no modifiers. (This
actually seems like a pretty big expressive deficiency for bitflags generated
structs.)
To avoid this problem keyseq::Modifiers is defined as Modifiers(pub u8) and
the bitflags are computed in the macro. That allows the following match
expressions to work as expected.
match
In addition keyseq::Modifiers implements From<ModifiersState> and vice
versa.
Bevy
Physical Keys
With the "bevy" feature the keyseq::bevy::pkey! macro returns a
(keyseq::Modifiers, KeyCode) tuple.
Bevy doesn't have a logical key representation so there are no lkey! and
lkeyseq! macros.
use KeyCode;
use ;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Logical Keys
With the "bevy" feature the keyseq::bevy::lkey! macro returns a
(Modifiers, Key) tuple.
use ;
use Key;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
assert_eq!;
Logical Key Sequences
# use Modifiers;
# use Key;
use lkeyseq;
assert_eq!;
Features
- winit, include support for winit
- bevy, include support for bevy
- poor, an anemic representation for internal testing
- strict-order, use a strict order for modifiers: Ctrl, Alt, Shift, Super (enabled by default)
Examples
For both examples press A with modifiers and it will print a message showing
what keychord matched.
Winit Example
Bevy Example
Notes
Macro Notation
Although using parentheses will work pkey!(Ctrl-Alt-A), rustfmt will add
spaces around the hyphen changing it to pkey!(Ctrl - Alt - A) as will square
brackets. Therefore, it is suggested to use curly braces pkey! { Ctrl-Alt-A }
which are not reformatted like that.
Compatibility
| keyseq | bevy | winit |
|---|---|---|
| 0.7.* | 0.17.* | 0.30.* |
| 0.6.* | 0.16.* | 0.30.* |
| 0.5.* | 0.15.* | 0.30.* |
| 0.4.* | 0.14.* | 0.30.* |
| 0.3.* | 0.14.* | 0.29.* |
| 0.2.0 | 0.13.* | 0.29.* |
| 0.1.0 | 0.12.* | 0.29.* |
License
This crate is licensed under the MIT License or the Apache License 2.0.