【问题标题】:In Linux, how can I intercept keyboard input and optionally filter it?在 Linux 中,如何拦截键盘输入并选择性地过滤它?
【发布时间】:2020-12-16 17:18:22
【问题描述】:

我正在编写一个跨平台应用程序,我希望能够拦截键盘输入并选择性地将其过滤到其他应用程序。我的应用程序加载插件,如果它有焦点,我试图阻止击键到达插件的 UI。

在 Window 上我使用 SetWindowsHookExA,在 macOS 上我使用 [NSEvent addLocalMonitorForEventsMatchingMask:]

有 Linux 的等价物吗?

【问题讨论】:

  • X11 没有应用的概念。没有什么可以阻止您的插件在自己的 X11 连接上运行自己的事件循环。
  • 有进展吗?我想创建一个类似于mos的linux应用

标签: linux keyboard keyboard-events


【解决方案1】:

我正在写一个跨平台的应用程序,我希望能够拦截键盘输入

如果您的应用程序是GUI,请考虑使用跨平台框架,例如QtGTK(或FLTKFOX 等...)。 如果您的应用程序是命令行的(例如grepGCCninjaMongoDB 是),它甚至可能无法访问键盘,如果在一些pipeline 中使用,你也可以使用像POCO 这样的跨平台框架。如果您的软件是由crontab 启动的,它甚至无法访问键盘,甚至可能不存在或未插入。

相同的源代码(用于 Qt 或 GTK 或 FLTK 等...)将适用于 Linux 和 Windows。

顺便说一句,许多 Linux 计算机(例如大多数 Web 服务器,或 RasperryPi)没有任何键盘或鼠标。

更多信息,请阅读Advanced Linux Programmingsyscalls(2)

了解XorgWayland

我的应用程序加载插件,如果它有焦点,我试图阻止击键到达插件的 UI。

Linux 上的Plugins 通常通过dlopen(3)dlsym(3) 实现为ELF 共享对象,通常在名为*.so 的文件中(参见elf(5))。阅读Program Library HowTo,如果您在C++ 中编码,还请阅读C++ dlopen minihowto。如果您在Ocaml 中编码,请使用Dynlink 模块。如果您可以在Common Lisp 中编码(例如使用SBCL),您只需使用eval。如果您必须在Java 中编码,请使用一些class loader

使用Xorg(即X11),每个键盘事件都会生成一些明确定义的消息(一些XKeyEvent) - 在tcp(7)unix(7) 套接字上-由Xorg 服务器发送到您的@ 987654357@ 客户端应用程序。

在客户端(在您的 GUI 应用程序代码中),event loop(在 poll(2)select(2)... 附近)正在等待此类消息。另见time(7)

在我的Debian 系统上(根据文件/var/log/Xorg.0.log 并使用proc(5)...)Xorg 服务器正在访问键盘(通过udev)作为/dev/input/event1X11 客户端communicatingXorg 服务器。

【讨论】:

    猜你喜欢
    • 2015-09-07
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    • 2018-12-09
    相关资源
    最近更新 更多