#mouse-event #keyboard-input #input #keyboard-events #hook #mouse #keyboard

bin+lib mki_fork

用于注册全局输入钩子和模拟键盘鼠标事件的Windows和Linux库。这是从mki的基本分支,更新了'input'依赖,使用了更新的libinput 1.19.1版本,而不是1.19.0。

1 个不稳定版本

0.2.1 2022年4月24日

#793 in 硬件支持

MIT 许可证

93KB
2.5K SLoC

mki - 鼠标键盘输入 crates.io 版本

用于注册全局输入钩子和模拟键盘鼠标事件的Windows & Linux库。

功能

  • 安装全局键/鼠标事件处理程序,无需绑定到单个键。
  • 安装每个键/按钮的事件处理程序。
  • 在按键时绑定动作。
  • 注册热键组合,如CTRL+Q,并在它们上触发动作。

示例

查看examples/readme.rs以获取示例。可以使用cargo run --example readme运行。

use mki::{bind_key, Action, InhibitEvent, Keyboard, Sequence};
use std::thread;
use std::time::Duration;

fn main() {
    Keyboard::A.bind(|_| {
        println!("A pressed, sending B");
        Keyboard::B.click();
    });
    mki::bind_any_key(Action::handle_kb(|key| {
        use Keyboard::*;
        if matches!(key, S | L | O | W | LeftShift | LeftControl | B) {
            // Ignore outputs from other commands for nicer output
        } else {
            println!("Some key pressed pressed: {:?}", key);
        }
    }));
    mki::bind_any_button(Action::handle_mouse(|button| {
        println!("Mouse button pressed {:?}", button);
    }));
    mki::register_hotkey(&[Keyboard::LeftControl, Keyboard::B], || {
        println!("Ctrl+B Pressed")
    });
    mki::bind_key(
        Keyboard::S,
        Action::sequencing_kb(|_| {
            Sequence::text("LLLLLow").unwrap().send();
            thread::sleep(Duration::from_secs(1));
        }),
    );

    // This binds action to a W key,
    // that W press will not be sent to the following services ( only on windows )
    // whenever Caps Lock is toggled
    // Action will be executed on separate thread.
    bind_key(
        Keyboard::W,
        Action {
            callback: Box::new(|event, state| {
                println!("key: {:?} changed state now is: {:?}", event, state);
            }),
            inhibit: InhibitEvent::maybe(|| {
                if Keyboard::CapsLock.is_toggled() {
                    InhibitEvent::Yes
                } else {
                    InhibitEvent::No
                }
            }),
            sequencer: false,
            defer: true,
        },
    );

    thread::sleep(Duration::from_secs(100));
}

示例2:配置文件

库支持使用yaml配置文件加载热键脚本。查看using_config.rs示例以获取更详细的示例。下面是一个简单的示例。

---
bind:
  - description: Whenever Ctrl+L is clicked click K as well
    key:
      - LeftControl
      - L
    action:
      click:
        key:
          - K

库提供了一个二进制文件mki,可以用来加载脚本。

mki 二进制文件

库提供了一个mki二进制文件,它接受一个参数,即.yaml文件的路径。文件将被解析,它将打印注册的热键类型,并无限期地监听输入。

它实际上是一个迷你热键应用程序。

线程模型

强烈建议使用默认的bind,它将为绑定生成新线程。
有一个选项可以sequence事件,这将使它们在一个单独的线程中依次调用。
有一个选项可以callback事件,这将调用检测到的线程。

使用的命名法

  • handle -> 启动一个新的线程。
  • sequence -> 在单个线程中排队给定的事件,该线程依次处理所有事件。
  • callback -> 在检测到键时在同一线程上调用回调,建议不要阻塞该线程或安排其他按键,因为这可能导致处理器被静默注销。

Linux

请注意,在Linux上运行应用程序需要root权限。

Linux依赖项

libxtst-dev

Linux注意事项

目前,Linux实现将在库的首次调用时休眠100毫秒。
否则,一些初始按键会被错过。

交叉开发linux -> windows

交叉。

在Linux上交叉编译Windows

cargo install cross
cross check --target x86_64-pc-windows-gnu

待办事项

  • 应该 are_pressed 支持鼠标吗?目前,配置中的 Pressed 忽略鼠标。
  • 在Linux和Windows上获取鼠标位置缺失。
未来的最终考虑因素
  • 放弃那些初始化时间不确定的静态状态,而是引入一个 Context。然而,来自库的回调仍然需要一个全局访问器,但这将绝对更好。
  • 应该移除序列化并引入通道方式吗?通过存储一个TX Vec可以传播事件。这有一个问题,那就是发送鼠标位置会有些尴尬。因为状态枚举与事件枚举是分开的。也许应该删除状态枚举,而是使用Up和Down?这将使键盘枚举变得有些混乱。

0.3版本发布计划

  • 很希望在Windows上支持多屏幕。目前我没有多屏幕,所以很难测试。
  • Linux支持鼠标实时跟踪回调
  • 添加一个调试模式 - --debug,当点击已注册的热键时会打印。

变更日志

0.2版本发布

  • 鼠标支持位置。
  • Windows支持鼠标实时跟踪回调。
  • 鼠标支持在给定坐标发送按键 - 添加click_at。
  • Linux显示使用方式现在非常丑陋,只需将其更改为lambda。
  • 各种API破坏性更改。

支持

如果您想感谢此存储库为您提供的东西,您可以通过 https://www.buymeacoffee.com/fulara 来表达。

依赖项

~1.9–3.5MB
~71K SLoC