在将Linux事件传递到任何应用程序之前,我想在Linux下对其进行钩挂,拦截和生成。更准确地说,我想检测关键事件流中的模式,并能够根据检测到的模式将事件丢弃/插入流中。
我在SO上看到了一些相关的问题,但是:
小型DSL
我在下面解释了这个问题,但是为了使其更加紧凑和易于理解,首先是一个小的DSL定义。
A_
:用于制作(按)键A A^
:换行(释放)键A A^->[C_,C^,U_,U^]
:在A^
上,向C发送一个make/break组合,然后向处理链的最后一个U发送(最后到应用程序)。如果没有->
,则不发送任何内容(但可以修改内部状态以检测后续事件)。 $X
:执行任意操作。这可以发送一些可配置的按键事件序列(例如emacs的C-x C-s
之类的东西),或执行一个函数。如果我只能发送键事件,那就足够了,因为然后我可以根据事件的应用程序在窗口管理器中进一步处理这些键事件。 问题描述
好的,因此使用此符号,这是我要检测的模式以及要在处理链中传递的事件。
A_, A^->[A_,A^]
:爆炸。参见上文,请注意发送发生在A^
上。 A_, B_, A^->[A_,A^], B^->[B_,B^]
:与1基本相同。但是重叠的事件不会改变处理流程。 A_, B_, B^->[$X], A^
:如果在按住另一个键(A)的同时完全完成了键(B)的创建/断开,则执行X(请参见上文),并丢弃A的断开。 (原则上,这是在键事件上实现的简单状态机,它可以生成(多个)键事件作为输出)。
补充笔记
可能的解决方案和问题
因此,基本问题是如何实现这一点。
我已经在窗口管理器中使用被动抓取(
XGrabKey
)和XSendEvent
实现了一个解决方案。不幸的是,被动抓取在这种情况下不起作用,因为它们无法在上面的第二种模式中正确捕获B^
。原因是转换后的抓取以A^
结尾,而不是继续到B^
。如果仍保持但仅在约1秒后,新的抓斗将转换为捕获B。否则,将普通的B^
发送到应用程序。可以使用xev
进行验证。我可以将实现转换为使用主动抓取(
XGrabKeyboard
),但是如果窗口管理器始终一直在键盘上进行主动抓取,则我不确定对其他应用程序的影响。 X文档将主动抓取称为侵入性的,并且设计用于短期使用。如果有人对此有经验,并且长期积极争取并没有重大弊端,那么我认为这是一个解决方案。除了窗口管理器(作为X客户端运行)之外,我还愿意查看其他关键事件处理层。键盘驱动程序或映射是可能的,只要我能用它们解决以上问题。这也意味着解决方案不必是单独的应用程序。我可以让驱动程序或内核模块为我做这件事。请注意,尽管我从未做过任何内核或驱动程序编程,所以我将感谢一些不错的资源。
感谢您的指导!
最佳答案
使用XInput2使设备(键盘) float ,然后监视设备上的KeyPress和KeyRelease事件,并使用XTest重新生成KeyPress和KeyRelease事件。
关于linux - 在Linux下删除/重写/生成键盘事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3781831/