Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用python evdev向uinput发送关于掩码键绑定问题的事件_Python_Linux_Input_Evdev - Fatal编程技术网

使用python evdev向uinput发送关于掩码键绑定问题的事件

使用python evdev向uinput发送关于掩码键绑定问题的事件,python,linux,input,evdev,Python,Linux,Input,Evdev,它的缺点是,我试图添加一个键绑定到我的程序,将编辑剪贴板,然后粘贴到任何你有活动窗口的更改。在Windows上,我想我可能可以通过消息传递来实现,但是X不使用这样的消息传递,所以为了实现这一点,我只使用向uinput发送ctrl+v事件。当您运行它时,它运行得相当好,但我需要它在键绑定上运行,在本例中是super+v。问题在于,当您将ctrl和v事件发送到uinput时,超级掩码仍然处于活动状态,因此它不会将ctrl+v发送到窗口,而是发送ctrl+super+v,而实际上不会执行任何操作。下面

它的缺点是,我试图添加一个键绑定到我的程序,将编辑剪贴板,然后粘贴到任何你有活动窗口的更改。在Windows上,我想我可能可以通过消息传递来实现,但是X不使用这样的消息传递,所以为了实现这一点,我只使用向uinput发送ctrl+v事件。当您运行它时,它运行得相当好,但我需要它在键绑定上运行,在本例中是super+v。问题在于,当您将ctrl和v事件发送到uinput时,超级掩码仍然处于活动状态,因此它不会将ctrl+v发送到窗口,而是发送ctrl+super+v,而实际上不会执行任何操作。下面是最简单的代码,可以准确地解释我所说的内容:

import evdev,time,keybinder,gtk

def callback():
    with evdev.UInput() as uinput:
        uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTCTRL, 1)
        uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_V, 1)
        uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_V, 0)
        uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTCTRL, 0)
        uinput.syn()

keybinder.bind("<super>v",callback)
keybinder.bind("Escape",gtk.main_quit)
gtk.main()
导入evdev、时间、密钥绑定器、gtk
def callback():
将evdev.UInput()作为UInput:
write(evdev.ecodes.EV_KEY,evdev.ecodes.KEY_LEFTCTRL,1)
uinput.write(evdev.ecodes.EV_KEY,evdev.ecodes.KEY_V,1)
uinput.write(evdev.ecodes.EV_KEY,evdev.ecodes.KEY_V,0)
write(evdev.ecodes.EV_KEY,evdev.ecodes.KEY_LEFTCTRL,0)
uinput.syn()
keybinder.bind(“v”,回调)
键绑定(“退出”,gtk.main_退出)
gtk.main()
如果您发布的速度足够快,您实际上可以让它工作,但它非常快,显然对于实际应用程序来说是不可接受的。我曾试图发布super,但这带来了一些问题;它不是很通用,它提出了一个问题,那就是以后该怎么做(让它保持释放状态?再按一次?如果它们在你释放之后再按一次之间的时间内释放会怎么样?),而且,最重要的是,它似乎真的不起作用


不管怎样,我想问题是,有没有办法解决这个问题?也许是一种发送不会与物理键盘结合的按键事件的方法(不太可能)?如果没有,有没有更好的方法让它在Linux上通用粘贴?

我认为这没有解决方案。正如您已经清楚地了解的,Ctrl-V不是用于启动“粘贴”操作的IPC机制,它只是一种常见的键绑定(请注意,如果您碰巧在前台运行emacs,您的小工具只会将窗口向上滚动一页,那么您的技巧将不起作用)。我认为你是对的,没有任何标准(例如freedesktop.org上的东西)要求窗口“立即粘贴”,也不应该有

至少正如应用程序通常理解和实现的那样,粘贴是用户发起的操作。没有任何应用程序会期望它由外部工具驱动。你想解决的实际问题是什么?你不能绑定一些东西在你的客户端应用程序中运行,或者挂接一个可访问性/输入法框架吗


这就是说:如果你想让这个特定的黑客程序正常工作,我认为你有正确的方法。在操作开始时查询它们的keymap,清除任何修改键的状态,发送事件,然后重置状态。显然,与硬件键盘的竞争仍然无法解决,但我怀疑在实践中这不会是一个大问题。

您需要找到一种方法来确定
键当前是否被按下。
在wxpython中,这将是
Super=wx.GetKeyState(wx.WXK\u META)
,我不知道在Gtk中会是什么。
那么您的代码如下所示:

def callback():
   Super = wx.GetKeyState(wx.WXK_META) # Here you require the Gtk equivalent 
   with evdev.UInput() as uinput:
        if Super:
            uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTMETA, 0)
        uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTCTRL, 1)
        uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_V, 1)
        uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_V, 0)
        uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTCTRL, 0)
        if Super:
            uinput.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTMETA, 1)
        uinput.syn()
如你所见,你差一点就得到了它。

添加的代码,只需在所需的Ctrl+v键之前关闭
Super
键,然后再次打开即可。

不幸的是,“我真的很想做”正是我所说的,我试图非常坦率。我不是用它作为发送文本的聪明方式,也不是试图以迂回的方式解决问题,我是在获取剪贴板数据并尝试粘贴它。问题是,你不一定每次都想使用这个应用程序的粘贴功能,否则我只会填充剪贴板,让用户使用它。至于emacs问题,该应用程序是用户可编写脚本的,因此他们可以添加一个键绑定(例如super+shift+v),允许它粘贴到正常情况下无法工作的地方。谢天谢地,我一直把最后那句话读得很无聊。我真的想不出更好的方式来表达它,我在尝试插入新行时意外提交了它,所以我没有时间修复它。只是要知道,这并不意味着,我感谢你的回应。好吧,这个应用程序基本上是放弃在这一点上。我想我试过这个(有一段时间了,但问题似乎提到了),但我遇到了比赛条件的问题。如果用户在粘贴前拿着super,我可以把它放回去,但他们也可以在粘贴后但在它写完之前释放super。然后你的超级按钮一直按下,直到你再次按下它。如果我不替换它,你不能粘贴多次。我相信我的最终解决方案是让用户手动选择从上下文菜单填充剪贴板,或者设置一个自动填充的选项。