1 个不稳定版本

0.1.0 2023年11月13日

#2035解析器实现

MIT/Apache

13KB
182

keybindings-parser

Rust

用于从字符串解析键绑定的微型库。并通过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_aXF86XK_MonBrightnessUp 等。

与修饰键不同,主键不区分大小写。换句话说,mod4 + amod4 + 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_Asuper + A 这样的快捷键是支持的,但并不合理,您可能需要 super + shift + asuper + shift + XK_a 分别。
  • 不支持如 mod4 + a + b 这样的键组合,应该只有一个主键。

在哪里获取 keysym?

关于 keysym 的长篇故事的简要总结:您必须将键事件中的 keycode 与 keysym 交换,keysym 可以从设备详细信息以及特定设备上键盘键映射的信息中获得。不存在静态 keycode 到 keysym 的映射表。

依赖关系

~650KB
~18K SLoC