1 个不稳定版本
0.1.0 | 2023年11月13日 |
---|
#2035 在 解析器实现
13KB
182 行
keybindings-parser
用于从字符串解析键绑定的微型库。并通过keysym & mod mask处理。
// init with default configuration
let mut keyb = Keybindings::default();
// add human readable keybinding
keyb.add("command + a", Box::new(TestAction::Kill))?;
// handle keybinging
if let Some(handler) = keyb.handle(ModMask::MOD4, keysymdefs::keys::XK_a) {
assert_eq!(handler.modifier(), ModMask::MOD4);
assert_eq!(handler.key(), keys::XK_a);
assert_eq!(handler.origin(), "command + a");
// action that you provide early
let action = handler.action();
action.run()?;
}
其中action
对象是一个实现了KeyAction
特质的对象。
pub trait KeyAction {
fn run(&self) -> Result<(), Box<dyn std::error::Error>>;
}
在现实中,键绑定处理程序将放置在event loop
的某个位置,例如。
// just for example, there are no event::next_event() constructions :)
loop {
let (mask, key) = event::next_event()?;
if let Some(handler) = keyb.handle(mask, key) {
handler.action().run()?;
}
}
可接受的修饰键
MOD4
被称为super
键可以描述为
- super
- mod4
- win
- windows
- cmd
- command
MOD1
被称为alt
键可以描述为
- alt
- mod1
- meta
- alt_l
- alt_r
- meta_l
- meta_r
MOD3
被称为AltGr
(现代键盘上不存在)键可以描述为
- alt_gr
- altgr
- mod3
- meta_gr
- metagr
CONTROL
键可以描述为
- ctrl
- control
- ctrl_l
- ctrl_r
SHIFT
键可以描述为
- shift
- shift_l
- shift_r
所有修饰键都在ModMask
枚举中描述。所有修饰键都是u32
值。所有修饰键都是位标志
。所有修饰键都不区分大小写。修饰键的位掩码与X11 KeyPress
事件值detail()
兼容。
主键
键绑定的主键。例如,mod4 + a
,其中a
是主键。接受来自keysymdefs::keys
的所有清除名称。例如
keys::XK_a
就是a
keys::XF86XK_MonBrightnessUp
实际上就是MonBrightnessUp
- 等等。
您可以使用键的全称,例如 XK_a
、XF86XK_MonBrightnessUp
等。
与修饰键不同,主键不区分大小写。换句话说,mod4 + a
与 mod4 + A
并不相同。此外,在键绑定上下文中,mod4 + A
也没有太多意义,因为 A
已经是修饰键 SHIFT
。因此,正确的做法是处理 mod4 + shift + a
。尽管如此,库将接受这种情况作为有效,您应该根据您的目标自行处理此类情况。
更改默认设置
let delimiter_char = '/';
let ghost_modifiers = ModMask::MOD4;
let keyb = Keybindings::new(delimiter_char, ghost_modifiers);
keyb.add("command / a", Box::new(TestAction::Kill))?;
// ...
// and then handle
let handler = keyb.handle(ModMask::MOD4, keysymdefs::keys::XK_a)?;
handler.run()?;
自定义 KeyAction 实现,用于示例
enum TestAction {
Kill,
ToggleFloat,
ToggleFullscreen,
ToggleTabBar,
SwapWindows,
Spawn(String),
}
impl KeyAction for TestAction {
fn run(&self) -> Result<(), Box<dyn std::error::Error>> {
match self {
TestAction::Kill => {}
TestAction::Spawn(_) => {}
TestAction::SwapWindows => {}
TestAction::ToggleFloat => {}
TestAction::ToggleFullscreen => {}
TestAction::ToggleTabBar => {}
};
Ok(())
}
}
您可以根据需要使用尽可能多的 KeyAction
实现。上述示例仅用于演示目的。
幽灵修饰符
有一些键盘切换不应该影响一般用途中键绑定的行为。其中
CAPS_LOCK
MOD2
更为人所知的是NumLock
MOD5
更为人所知的是ScrollLock
它们都在 Keybindings::default()
中默认忽略。如果您想更改这些预设选项,请使用 new()
而不是 default()
,例如。
let key_delimiter = '/';
let ghost_modifiers = ModMask::MOD4 | ModMask::MOD5;
let keyb = Keybindings::new(key_delimiter, ghost_modifiers);
限制和注意事项
- 键绑定的数量没有限制。您可以添加尽可能多的。
- 动作的数量也没有限制。您可以添加尽可能多的。
- 键盘快捷键可能根本不包含修饰符(例如
Print
键)。 - 但是,键盘快捷键不能没有主键(例如
"super"
) - 修饰键不区分大小写,主键区分大小写
- 完全重复键盘快捷键会在添加时导致错误
- 尽管如此,可以添加具有相同主键和不同修饰键的键绑定
- 如
super + XK_A
或super + A
这样的快捷键是支持的,但并不合理,您可能需要super + shift + a
或super + shift + XK_a
分别。 - 不支持如
mod4 + a + b
这样的键组合,应该只有一个主键。
在哪里获取 keysym?
关于 keysym 的长篇故事的简要总结:您必须将键事件中的 keycode 与 keysym 交换,keysym 可以从设备详细信息以及特定设备上键盘键映射的信息中获得。不存在静态 keycode 到 keysym 的映射表。
依赖关系
~650KB
~18K SLoC